Assíncrono: callbacks, promises, async/await
Por que buscar dado de uma API não trava a página — e como o código foi evoluindo pra lidar com isso.
JavaScript roda em uma única thread — mas buscar dado de uma API leva tempo (rede é lenta perto de CPU) e a página não pode simplesmente "travar" esperando. A solução: operações demoradas são assíncronas — o código continua rodando, e você é avisado quando o resultado chega.
1ª geração: callback
setTimeout(() => {
console.log("Isso roda depois de 1 segundo");
}, 1000);
console.log("Isso roda ANTES do de cima, mesmo vindo depois no código");Callback funciona, mas encadear várias operações assíncronas em sequência (buscar usuário, depois os pedidos dele, depois os detalhes de cada pedido) vira um aninhamento profundo de funções dentro de funções — o "callback hell" que motivou a próxima geração.
2ª geração: Promise
function buscarUsuario(id) {
return fetch(`/api/usuarios/${id}`).then((res) => res.json());
}
buscarUsuario(1)
.then((usuario) => console.log(usuario))
.catch((erro) => console.error("Deu erro:", erro));Uma Promise representa "um valor que ainda não existe, mas vai existir (ou vai falhar)". .then() encadeia o que fazer quando der certo; .catch(), quando der errado — mais legível que callback aninhado, mas ainda assim uma cadeia de .then().
3ª geração: async/await — o padrão hoje
async function buscarUsuario(id) {
try {
const res = await fetch(`/api/usuarios/${id}`);
const usuario = await res.json();
return usuario;
} catch (erro) {
console.error("Deu erro:", erro);
}
}async/await não é uma tecnologia diferente de Promise — é a mesma coisa, com uma sintaxe que lê como código síncrono normal. await "pausa" a função (só ela, não a página inteira) até a Promise resolver. try/catch substitui o .catch() encadeado. É por isso que todo componente async do Next.js usa exatamente essa sintaxe.
Rodando promises em paralelo
// sequencial — espera uma terminar pra começar a próxima (mais lento)
const usuario = await buscarUsuario(1);
const produtos = await buscarProdutos();
// paralelo — as duas requisições saem ao mesmo tempo (mais rápido)
const [usuario2, produtos2] = await Promise.all([
buscarUsuario(1),
buscarProdutos(),
]);Exercício
Duas funções buscarPerfil() e buscarNotificacoes() não dependem uma da outra. Escreva o código que busca as duas em paralelo, usando async/await.