Depuração prática, passo a passo

Quando falta await, o código usa a Promise antes do resultado

Uma função async devolve imediatamente uma Promise, isto é, uma representação de um resultado que ainda pode chegar. Sem await, a linha seguinte usa essa Promise como se já tivesse recebido o valor final.

DoesItHold Editorial · · revisado em · guide-js-await-001

Resposta direta

Coloque await antes da chamada no primeiro ponto em que o resultado pronto é necessário. A função que contém esse await também precisa ser async.

No exemplo, fetchUser() ainda não devolveu o usuário quando a linha seguinte tenta ler user.name. Por isso, o código acessa uma propriedade da Promise, e não do usuário resolvido. O erro pode aparecer ali ou somente depois, quando esse valor chega a outra parte do programa.

Pense no defeito como uma ordem de execução incorreta. Pergunte: ‘qual é a primeira linha que realmente precisa do usuário pronto?’. Colocar await nesse ponto deixa a dependência visível sem obrigar tarefas independentes a esperar umas pelas outras.

Rastreie a falha
  1. ChamadafetchUser() retorna Promise<User>
  2. Limitename é necessário de modo síncrono
  3. Suspensãoawait cede esta continuação
  4. Retomadauser agora contém o User resolvido
await não bloqueia a thread. Ele suspende esta continuação assíncrona até a Promise terminar e então retoma com o valor resolvido.

Exemplo mínimo

Deslize para ver todo o código

Com defeito
async function loadName() {
  const user = fetchUser();
  return user.name;
}
Corrigido
async function loadName() {
  const user = await fetchUser();
  return user.name;
}

O que muda: A versão corrigida lê name somente depois que user contém o valor resolvido; a versão com defeito tenta ler a propriedade de Promise<User>.

Método de depuração

Observe o valor durante a execução, encontre a primeira linha que precisa do resultado pronto e coloque await imediatamente antes desse uso.

  1. Confirme se o valor observado é uma Promise antes de alterar o código.
  2. Encontre o primeiro acesso, comparação ou cálculo que precisa do resultado pronto.
  3. Torne a função externa async e adicione await nesse ponto.
  4. Teste tanto o sucesso quanto a rejeição da Promise para não esconder um novo erro.

Correção incorreta comum

Adicionar um tempo de espera, optional chaining ou outra Promise apenas esconde o sintoma. Espalhar await por todas as expressões também pode fazer operações independentes rodarem uma depois da outra sem necessidade.

Limites e casos-limite

O uso de await fora de uma função depende do ambiente de script ou módulo. Dentro de laços, ele também pode fazer requisições independentes rodarem em sequência. Quando elas puderem começar juntas, use Promise.all somente no ponto em que todos os resultados forem necessários.

Fontes