---
title: "E0728: await Usado Fora de Função Async no Rust"
url: "https://rustlang.com.br/erros/e0728-await-fora-async/"
markdown_url: "https://rustlang.com.br/erros/e0728-await-fora-async.MD"
description: "Como resolver o erro E0728 do Rust: .await usado fora de contexto async. Entenda quando e onde usar async/await e como estruturar código assíncrono corretamente."
date: "2026-02-23"
author: "Equipe Rust Brasil"
---

# E0728: await Usado Fora de Função Async no Rust

Como resolver o erro E0728 do Rust: .await usado fora de contexto async. Entenda quando e onde usar async/await e como estruturar código assíncrono corretamente.


# E0728: await Usado Fora de Função Async

O erro **E0728** ocorre quando você usa `.await` em um contexto que **não é async** — ou seja, fora de uma função `async fn`, um bloco `async {}` ou uma closure `async`. O `.await` só pode ser usado dentro de contextos assíncronos.

## A Mensagem de Erro

```
error[E0728]: `await` is only allowed inside `async` functions and blocks
 --> src/main.rs:5:29
  |
4 | fn buscar_dados() -> String {
  |    ------------ this is not `async`
5 |     let resposta = reqwest::get("https://api.exemplo.com").await;
  |                                                           ^^^^^^ only allowed inside `async` functions and blocks
```

Variação em closure não-async:

```
error[E0728]: `await` is only allowed inside `async` functions and blocks
 --> src/main.rs:3:38
  |
3 |     let processar = |url| { fetch(url).await };
  |                     -----              ^^^^^^ only allowed inside `async` functions and blocks
  |                     |
  |                     this is not `async`
```

## O Que Significa

No Rust, `async`/`await` é um mecanismo de programação assíncrona que permite escrever código não-bloqueante de forma legível. O `.await` pausa a execução da função atual até que o future (operação assíncrona) seja concluído.

Porém, `.await` só funciona dentro de um **contexto async** porque:

1. Funções async são transformadas em **máquinas de estado** pelo compilador
2. O `.await` marca os **pontos de pausa** nessa máquina de estado
3. Funções síncronas normais não têm essa infraestrutura

Sem o contexto async, o compilador não sabe como gerar a máquina de estado necessária para pausar e retomar a execução.

## Código com Erro

### Função síncrona tentando usar await

```rust
// ERRO: função não é async
fn buscar_dados() -> String {
    let corpo = reqwest::get("https://api.exemplo.com")
        .await  // ERRO: não está em contexto async
        .unwrap()
        .text()
        .await  // ERRO: mesmo problema
        .unwrap();
    corpo
}
```

### main() sem macro async

```rust
// ERRO: main normal não é async
fn main() {
    let dados = buscar_dados().await;  // ERRO
    println!("{}", dados);
}

async fn buscar_dados() -> String {
    "dados".to_string()
}
```

### Closure não-async

```rust
async fn processar_urls(urls: Vec<String>) {
    let resultados: Vec<_> = urls.iter().map(|url| {
        // ERRO: closure não é async
        reqwest::get(url).await
    }).collect();
}
```

## Como Resolver

### Solução 1: Tornar a Função Async

Adicione `async` à declaração da função:

```rust
// CORRETO: função async
async fn buscar_dados() -> String {
    let corpo = reqwest::get("https://api.exemplo.com")
        .await
        .unwrap()
        .text()
        .await
        .unwrap();
    corpo
}
```

**Lembre-se:** uma função `async fn` retorna um `Future`, não o valor diretamente. O chamador precisa usar `.await` (que também precisa estar em contexto async).

### Solução 2: Usar Runtime Async para main()

Com **tokio**:

```rust
#[tokio::main]
async fn main() {
    let dados = buscar_dados().await;
    println!("{}", dados);
}

async fn buscar_dados() -> String {
    "dados".to_string()
}
```

Certifique-se de ter as features corretas:

```toml
[dependencies]
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
```

Com **async-std**:

```rust
#[async_std::main]
async fn main() {
    let dados = buscar_dados().await;
    println!("{}", dados);
}
```

### Solução 3: Usar Bloco `async {}` dentro de Contexto Síncrono

Para executar código async em contexto síncrono, use `block_on`:

```rust
fn main() {
    let rt = tokio::runtime::Runtime::new().unwrap();

    let resultado = rt.block_on(async {
        buscar_dados().await
    });

    println!("{}", resultado);
}

async fn buscar_dados() -> String {
    "dados do servidor".to_string()
}
```

Ou com a versão simplificada:

```rust
fn funcao_sincrona() -> String {
    // Cria runtime temporário para executar código async
    tokio::runtime::Runtime::new()
        .unwrap()
        .block_on(buscar_dados())
}

async fn buscar_dados() -> String {
    "dados".to_string()
}
```

**Cuidado:** Não use `block_on` dentro de um contexto que já está em um runtime async — isso causa deadlock.

### Solução 4: Closures Async

Para closures, use a sintaxe `async`:

```rust
async fn processar_urls(urls: Vec<String>) {
    // Use futures::future::join_all para processar em paralelo
    let futures = urls.into_iter().map(|url| {
        async move {  // Closure async
            let resp = reqwest::get(&url).await.unwrap();
            resp.text().await.unwrap()
        }
    });

    let resultados: Vec<String> = futures::future::join_all(futures).await;
    println!("{:?}", resultados);
}
```

Ou processe sequencialmente com um loop:

```rust
async fn processar_sequencial(urls: Vec<String>) {
    for url in &urls {
        let resp = reqwest::get(url).await.unwrap();
        let corpo = resp.text().await.unwrap();
        println!("URL: {} -> {} bytes", url, corpo.len());
    }
}
```

### Solução 5: Traits com Métodos Async

Para traits com métodos async, use o crate `async-trait` ou a sintaxe nativa (estabilizada no Rust 1.75+):

```rust
// Com async-trait (compatível com versões anteriores)
use async_trait::async_trait;

#[async_trait]
trait Repositorio {
    async fn buscar(&self, id: u64) -> Option<String>;
    async fn salvar(&self, id: u64, valor: String) -> Result<(), String>;
}

struct BancoDeDados;

#[async_trait]
impl Repositorio for BancoDeDados {
    async fn buscar(&self, id: u64) -> Option<String> {
        Some(format!("Item {}", id))
    }

    async fn salvar(&self, id: u64, valor: String) -> Result<(), String> {
        println!("Salvando {} = {}", id, valor);
        Ok(())
    }
}
```

## Resumo: Onde `.await` Funciona

| Contexto | Pode usar `.await`? |
|---|---|
| `async fn` | Sim |
| `async { ... }` bloco | Sim |
| `async move { ... }` | Sim |
| `fn` normal | Nao |
| Closure `\|\| { ... }` | Nao |
| `async \|\| { ... }` | Sim |
| `#[tokio::main] async fn main()` | Sim |
| `fn main()` sem macro | Nao |

## Veja Também

- [Future is Not Send](/erros/future-not-send/)
- [Cargo: Could Not Compile](/erros/cargo-could-not-compile/)
- [Tutorial de Tratamento de Erros](/tutoriais/tratamento-de-erros/)
- [Cheatsheet Rust](/cheatsheet/)
- [Documentação oficial: E0728](https://doc.rust-lang.org/error_codes/E0728.html)
