JavaScript: Programação Assíncrona em JavaScript
Última atualização: 2026-10-13
JavaScript é single-threaded — só consegue fazer uma coisa por vez. Mas se uma requisição de rede leva 3 segundos, a página deve congelar por 3 segundos? Claro que não. A programação assíncrona resolve isso: em vez de esperar, você pega uma senha e volta quando estiver pronto. Como um sistema de fila de restaurante — você não fica na porta da cozinha, senta e espera sua senha ser chamada.
1. Síncrono vs Assíncrono
Síncrono: O código executa linha por linha — a próxima linha espera a atual terminar. Como ficar na fila — você espera até que a pessoa à sua frente termine.
Assíncrono: Certas operações (requisições de rede, temporizadores, E/S de arquivo) iniciam sem bloquear o código subsequente. Quando terminam, você é notificado via callback ou Promise.
<script>
console.log('1');
setTimeout(function() {
console.log('2');
}, 1000);
console.log('3');
</script>
A ordem de saída é 1 → 3 → 2. setTimeout é assíncrono — seu callback executa após 1 segundo sem bloquear console.log('3').
Callbacks são o padrão assíncrono mais básico — passe uma função como argumento, e ela será chamada quando a operação assíncrona completar.
▶ Exemplo: Uso Básico de Callback
▶ Experimente(1) Callback Hell
Quando operações assíncronas dependem umas das other em sequência, callbacks ficam cada vez mais aninhados — este é o infame "Callback Hell."
<script>
obterUsuario(function(usuario) {
obterPedidos(usuario.id, function(pedidos) {
obterDetalhePedido(pedidos[0].id, function(detalhe) {
obterItens(detalhe.itemId, function(itens) {
console.log('4 níveis de profundidade — adicione mais complexidade e fica ilegível');
});
});
});
});
</script>
3. Promise
Uma Promise é um objeto que representa o resultado eventual de uma operação assíncrona. Tem três estados:
| Estado | Descrição |
|---|---|
pending |
Em andamento, sem resultado ainda |
fulfilled |
Completado com sucesso, resultado disponível |
rejected |
Falhou, erro disponível |
Quando uma Promise transiciona de pending para fulfilled ou rejected, ela nunca volta atrás — como uma flecha uma vez disparada, não pode ser chamada de volta.
(1) Criando uma Promise
<script>
const promise = new Promise(function(resolve, reject) {
// operação assíncrona
// chame resolve(resultado) em caso de sucesso
// chame reject(erro) em caso de falha
});
</script>
(2) then / catch / finally
<script>
promise
.then(function(resultado) { console.log(resultado); }) // executa em caso de sucesso
.catch(function(erro) { console.error(erro); }) // executa em caso de falha
.finally(function() { console.log('Concluído'); }); // executa sempre
</script>
▶ Exemplo: Simulando uma Requisição com Promise
▶ Experimente(3) Encadeamento
then em si retorna uma Promise, então você pode encadear chamadas — callback hell vira uma linha reta.
<script>
buscarUsuario()
.then(function(usuario) { return buscarPedidos(usuario.id); })
.then(function(pedidos) { return buscarDetalhe(pedidos[0].id); })
.then(function(detalhe) { console.log(detalhe); })
.catch(function(err) { console.error(err); });
</script>
catch no final do encadeamento captura erros de qualquer etapa — você não precisa de um catch após cada then.
4. async / await
async/await é açúcar sintático sobre Promisses — faz código assíncrono parecer síncrono, melhorando muito a legibilidade.
async: Declara uma função assíncrona que automaticamente retorna uma Promiseawait: Pausa a execução até a Promise ser resolvida, depois retorna o resultado
▶ Exemplo: Reescrevendo a Requisição Acima com async/await
▶ Experimenteasync/await transforma "pegar uma senha e esperar" em "ficar na fila sem sair" — o fluxo do código é reto e a legibilidade vai lá em cima.
(1) Tratamento de Erros
async/await usa try/catch para tratamento de erros — o mesmo padrão usado com código síncrono.
<script>
async function carregarTudo() {
try {
const usuario = await buscarUsuario();
const pedidos = await buscarPedidos(usuario.id);
console.log(pedidos);
} catch (err) {
console.error('Algo deu errado:', err);
}
}
</script>
5. Promise.all e Promise.race
| Método | Descrição |
|---|---|
Promise.all([p1, p2, p3]) |
Sucesso apenas se todas tiverem sucesso; falha assim que uma falhar |
Promise.race([p1, p2, p3]) |
Usa o resultado da primeira a resolver (sucesso ou falha) |
▶ Exemplo: Requisições Concorrentes com Promise.all
▶ ExperimentePromise.all é como um jantar em grupo — todos devem chegar antes de comer. Promise.race é como uma corrida — quem terminar primeiro ganha. Use all para requisições independentes para acelerar, e race quando tiver múltiplas fontes espelho e quiser a mais rápida.
❓ Perguntas Frequentes
await pode ser usado em uma função comum?await só pode ser usado dentro de uma função async. Usar await em uma função comum causa erro de sintaxe. await de nível superior é suportado em módulos, mas o suporte do navegador varia.Promise.all falhar?Promise.all rejeita imediatamente com o primeiro erro. Outras Promises ainda executam, mas seus resultados são ignorados. Se precisar de "todas resolvidas independentemente do resultado," use Promise.allSettled.async retorna?async sempre retorna uma Promise. Mesmo que você faça return 42, na verdade retorna Promise.resolve(42). Então você pode usar .then() para consumir o resultado.📖 Resumo
- Código síncrono bloqueia execução subsequente; código assíncrono não — single-threaded ainda consegue "fazer várias coisas"
- Callbacks são o padrão assíncrono mais básico; aninhamento profundo cria callback hell
- Promise tem três estados:
pending → fulfilledoupending → rejected— transições de estado são irreversíveis then/catch/finallyconsomem Promisses; encadeamento resolve callback hellasync/awaité açúcar sintático sobre Promises;awaitsó pode ser usado dentro de funçõesasyncPromise.allespera todas terem sucesso;Promise.racepega a primeira a resolver
📝 Exercícios
- Básico: Use
Promise+setTimeoutpara simular um atraso de 2 segundos, depois exiba "Concluído" em caso de sucesso. - Intermediário: Reescreva o acima com
async/awaite adicione tratamento de erros comtry/catch. - Desafio: Use
Promise.allpara disparar 3 requisições simuladas com atrasos diferentes (1s/2s/3s) concorrentemente, depois calcule e exiba o tempo total decorrido quando todas completarem.