DoesItHold

O bug do await ausente em funções async do JavaScript

Numa função async, chamar uma função que retorna uma Promise te dá a Promise, não o valor resolvido. Esqueça o await e a próxima linha lê uma Promise pendente como se o dado já estivesse ali.

A resposta rápida

Adicione await antes da chamada que retorna uma Promise. Sem ele, o valor retornado é um objeto Promise, então ler uma propriedade ou chamar um método no dado esperado não se comporta como você pretende.

Um exemplo mínimo

Com bug: a resposta é uma Promise, não o resultado do fetch
async function showUser() {
  const user = getUser();
  console.log(user.name);
}
Corrigido: o await resolve a Promise primeiro
async function showUser() {
  const user = await getUser();
  console.log(user.name);
}

Na versão com bug, response é uma Promise. Por isso, chamar json() sobre ela não lê o corpo já convertido. Com await, response recebe o valor resolvido antes da execução da linha seguinte.

Como depurar

  1. Encontre toda chamada que retorna uma Promise: fetch, drivers de banco e a maioria das operações de I/O.
  2. Verifique se o valor retornado é usado diretamente na linha seguinte.
  3. Siga o valor: se uma Promise é tratada como dado comum, falta um await.
  4. Adicione await, ou retorne a Promise para que quem chamou possa aguardá-la.

Correções erradas comuns

  • Encapsular a chamada em outra Promise em vez de aguardar a que você já tem.
  • Adicionar .then num lugar mas deixar o valor sendo usado de forma síncrona logo depois.
  • Marcar a função como async sem nunca aguardar a Promise dentro dela.

Limites deste guia

Isto cobre o caso de um único await ausente. Bugs assíncronos reais também incluem rejeições não tratadas, corridas entre awaits concorrentes e ordenação entre event loops. O desafio foca no erro de ordenação mostrado aqui.

Referências oficiais

  1. Especificação da linguagem ECMAScript — Await
  2. MDN — função async
  3. MDN — operador await

Pronto para experimentar?

Corrigir este bug em um desafio grátis

Páginas relacionadas