Aprenda / JavaScript do zero

FundamentosAula 7 de 1618 min0% da trilha

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.

Quiz rápido

async/await é uma tecnologia diferente de Promise?
Por que usar Promise.all em vez de dois await sequenciais, quando as buscas são independentes?