Capítulo 4.5: Async/await vs Promise
Tempo de estudo: 30 minutos
1. Assincronicidade: Duas maneiras de gerenciar a "comunicação espacial"
Imagine que o Centro de Controle da Missão (CCM) envie um comando para Marte. A resposta só chegará em alguns minutos. Como organizar o trabalho durante esse tempo?
Maneira 1: "Protocolo de Retorno de Chamada" (Promise com .then()
)
Você envia um comando e dá uma instrução: "QUANDO a resposta chegar, ENTÃO execute esta função". Isso é parecido com uma cadeia de eventos.
Maneira 2: "Modo de Espera" (Async/await) Você diz: "Eu VOU ESPERAR a resposta para este comando, mas não vou bloquear outros consoles de controle". É como se você pausasse a execução desta tarefa específica, permitindo que o resto do CCM continue trabalhando.
Ambas as maneiras resolvem a mesma tarefa — gerenciar operações assíncronas. async/await
é simplesmente uma sintaxe mais moderna e legível que funciona "em cima" das promises.
💡 Analogia espacial:
- Promise com
.then()
: É como escrever num post-it: "Quando o rover de Marte enviar a foto, encaminhá-la para o departamento de análise".- Async/await: É como dizer ao assistente: "Espere pela foto do rover de Marte, enquanto isso vou fazer os cálculos para o lançamento de um novo foguete".
2. Promise com .then()
: Cadeia de comandos clássica
Esta é a maneira fundamental de trabalhar com assincronicidade em JavaScript, que usamos no Capítulo 4.1.
Vamos relembrar nosso primeiro código:
function getIssPositionWithPromises() {
console.log('Enviando solicitação via protocolo "Promise"...');
fetch('http://api.open-notify.org/iss-now.json')
.then(response => {
// Etapa 1: Resposta recebida
if (!response.ok) {
throw new Error(`Erro HTTP: ${response.status}`);
}
return response.json(); // Retornamos uma nova promise
})
.then(data => {
// Etapa 2: Dados analisados
console.log('Dados via protocolo "Promise" recebidos:', data.iss_position);
})
.catch(error => {
// Etapa 3 (Erro): Algo deu errado em qualquer uma das etapas
console.error('Falha de comunicação via protocolo "Promise":', error);
});
console.log('...comando enviado, CCM continua trabalhando...');
}
Vantagens:
- Cadeia explícita de ações.
- Adequado para operações sequenciais simples.
Desvantagens:
- "Inferno de Callbacks" (Callback Hell): Com um grande número de operações assíncronas aninhadas, o código pode se transformar numa "escadaria" de
.then()
, o que dificulta a leitura. - O tratamento de erros pode ser menos intuitivo.
3. Async/await: Estilo síncrono moderno
async/await
é "açúcar sintático" sobre promises, que permite escrever código assíncrono como se fosse síncrono.
Regras de uso:
- A palavra-chave
await
pode ser usada apenas dentro de uma função marcada comoasync
. await
é colocado antes de uma chamada que retorna uma promise (por exemplo,fetch()
ouresponse.json()
).await
"pausa" a execução da funçãoasync
até que a promise seja resolvida, e retorna o seu resultado.
O mesmo código, reescrito com async/await
:
async function getIssPositionWithAsyncAwait() {
console.log('Enviando solicitação via protocolo "Async/await"...');
try {
// Etapa 1: Esperando resposta do servidor
const response = await fetch('http://api.open-notify.org/iss-now.json');
if (!response.ok) {
throw new Error(`Erro HTTP: ${response.status}`);
}
// Etapa 2: Esperando que o corpo da resposta seja convertido para JSON
const data = await response.json();
console.log('Dados via protocolo "Async/await" recebidos:', data.iss_position);
} catch (error) {
// Etapa 3 (Erro): Capturamos qualquer erro do bloco try
console.error('Falha de comunicação via protocolo "Async/await":', error);
}
console.log('...comando enviado, CCM continua trabalhando...');
}
Vantagens:
- Legibilidade: O código parece quase um código síncrono comum, é fácil de ler de cima para baixo.
- Tratamento de erros: Usa o bloco
try...catch
padrão e familiar. - Depuração: Muito mais fácil de depurar, pois você pode colocar pontos de interrupção (breakpoints) em cada linha com
await
.
Desvantagens:
- Fácil esquecer
await
ouasync
, o que levará a erros.
4. Quando usar qual protocolo?
Situação | Abordagem recomendada | Porquê? |
---|---|---|
Maioria dos casos | async/await |
O código é mais limpo, mais fácil de ler e depurar. Este é o padrão moderno. |
Cadeia simples de 1-2 ações | Promise com .then() |
Totalmente adequado, o código permanece compacto. |
Execução paralela de várias requisições | Promise.all() |
Este método permite executar várias promises simultaneamente e esperar que todas sejam concluídas. async/await combina perfeitamente com ele. |
Exemplo com Promise.all()
:
async function getParallelData() {
try {
// Executamos ambas as requisições simultaneamente
const [shipsResponse, launchesResponse] = await Promise.all([
fetch('https://api.spacexdata.com/v4/rockets'),
fetch('https://api.spacexdata.com/v4/launches/latest')
]);
if (!shipsResponse.ok || !launchesResponse.ok) {
throw new Error('Uma das requisições falhou!');
}
const rockets = await shipsResponse.json();
const latestLaunch = await launchesResponse.json();
console.log(`Total de foguetes na frota: ${rockets.length}`);
console.log(`Último lançamento: ${latestLaunch.name}`);
} catch (error) {
console.error('Erro ao obter dados paralelos:', error);
}
}
Quiz para fixação
🚀 Resumo do Capítulo:
Você aprendeu duas sintaxes para gerenciar operações assíncronas e entendeu por que async/await
é preferível na maioria dos projetos modernos.
- 🔗 Você revisou seus conhecimentos sobre Promise com
.then()
. - 🛠️ Você compreendeu profundamente como funciona
async/await
e suas vantagens. - ⚡ Você aprendeu sobre
Promise.all
para executar requisições paralelas.
Protocolos de comunicação aprendidos! No capítulo final desta seção, reuniremos todo o nosso conhecimento e construiremos nosso "Centro de Controle de Voo", criando uma interface completa para todas as operações CRUD.
📌 Prática:
- Reescreva todas as funções em seu
app.js
que ainda usam.then()
, para a sintaxeasync/await
.- Tente adicionar mais uma requisição a
Promise.all()
(por exemplo, parahttps://api.spacexdata.com/v4/starlink
) e exiba os dados.⚠️ Se houver erros:
await is only valid in async functions
: Certifique-se de que a função onde você usaawait
esteja marcada comoasync
.A variável contém [object Promise]
: Você esqueceu de colocarawait
antes da função que retorna uma promise.