async/await em Node
async/await torna o código assíncrono do Node parecido com código síncrono, mantendo a semântica de Promises - a vantagem é a clareza se você preservar o contexto de erro e evitar serializar I/O independente.
Busque em todas as páginas da documentação
async/await torna o código assíncrono do Node parecido com código síncrono, mantendo a semântica de Promises - a vantagem é a clareza se você preservar o contexto de erro e evitar serializar I/O independente.
async function fetchUser(id: string) {
const res = await fetch(`https://api.example.com/users/${id}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json() as Promise<{ id: string; name: string }>;
}
try {
const user = await fetchUser('42');
console.log(user.name);
} catch (err) {
console.error('fetchUser falhou:', err);
}Quando usar isso:
.then() em código brownfieldimport { createServer } from 'node:http';
interface User { id: string; name: string }
const users = new Map<string, User>([['1', { id: '1', name: 'Ada' }]]);
async function getUser(id: string): Promise<User> {
await new Promise((r) => setTimeout(r, 10)); // simula latência do DB
const user = users.get(id);
if (!user) throw new Error(`Usuário ${id} não encontrado`);
return user;
}
const server = createServer(async (req, res) => {
try {
const id = req.url?.split('/').pop() ?? '';
const user = await getUser(id);
res.writeHead(200, { 'content-type': 'application/json' });
res.end(JSON.stringify(user));
} catch (err) {
const message = err instanceof Error ? err.message : 'Erro desconhecido';
const status = message.includes('não encontrado') ? 404 : 500;
res.writeHead(status, { 'content-type': 'application/json' });
res.end(JSON.stringify({ error: message }));
}
});
server.listen(3000);O que isso demonstra:
async retornam Promises - erros devem ser capturados por solicitaçãotry/catch em torno de await mapeia falhas para códigos de status HTTPError preserva mensagens para clientes e logsawait não bloqueia outras solicitações, a menos que você use await sequencialmente dentro de um lockasync function sempre retorna uma Promise - mesmo que você return 42.await pausa a função até que a Promise seja resolvida, agendando o restante como microtarefas.async se tornam Promises rejeitadas.// Lento: sequencial (latência se acumula)
const a = await fetchA();
const b = await fetchB();
// Rápido: I/O independente paralelo
const [a, b] = await Promise.all([fetchA(), fetchB()]);// Padrão Result tipado para falhas esperadas (opcional)
type Result<T, E = Error> = { ok: true; value: T } | { ok: false; error: E };
async function safeFetch(url: string): Promise<Result<unknown>> {
try {
const res = await fetch(url);
return { ok: true, value: await res.json() };
} catch (error) {
return { ok: false, error: error instanceof Error ? error : new Error(String(error)) };
}
}try/catch ou hooks de erro do framework (Express 5 melhora isso).await sequencial em loops - for (const id of ids) await fetch(id) é lento. Correção: Promise.all com limite de concorrência (p-limit).await - fire-and-forget perde o contexto de erro. Correção: void doWork().catch(log) intencionalmente, ou await.util.promisify ou fs/promises.import() dinâmico e preguiçoso para dependências pesadas.| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
Raw Promises .then() | Interoperabilidade com bibliotecas estilo callback | A legibilidade de ramificações complexas sofre |
Promise.allSettled | Lotes de sucesso parcial | Todos devem ter sucesso atomicamente |
| Fluxos reativos (RxJS) | Composição de eventos ao longo do tempo | Manipuladores simples de requisição/resposta |
| Código síncrono | CPU pura em dados pequenos | Qualquer I/O ou rede |
await suspende apenas a função async, não a thread. Outras requisições rodam até que sua continuação seja retomada como uma microtarefa.
Envolva em try/catch e chame next(err), ou use um wrapper que encaminhe rejeições para o middleware de erro.
Sim em ESM ("type": "module"). Os importadores esperam o módulo terminar de inicializar.
Chamar uma função async sem await ou .catch() - rejeições podem se tornar não tratadas.
Use uma biblioteca de pool ou agrupe IDs em blocos em vez de Promise.all ilimitado em milhares de itens.
Sim - todos os métodos fs/promises retornam Promises adequadas para await.
for await (const chunk of stream) consome iteráveis assíncronos - comum com streams e corpos de fetch.
Sim quando realiza I/O. Garanta que o framework aguarde os valores de retorno do middleware (Express 5, Fastify 5 fazem isso).
throw new Error('Falha no DB', { cause: originalErr });Preserva o contexto aninhado da pilha no Node 24.
Geralmente sim com await. Misturas profundas de callbacks sem promisify ainda podem perder contexto.
Valores de retorno e erros lançados se integram ao ciclo de vida de resposta do Fastify - ainda prefira validação explícita nas fronteiras.
Caminhos quentes com centenas de microtarefas onde uma máquina de estados é mais clara - raro em APIs CRUD típicas.
Versões da Pilha: Esta página foi escrita para Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5 e NestJS 11.
Revisado por Chris St. John·Última atualização: 19 de jul. de 2026