Olá, pessoal!
Hoje quero mostrar pra vocês uma forma de capturar os erros de um async await sem usar o try catch.
Mas primeiro vamos recaptular, o que é mesmo um async await?
async/await
Vou tentar contar a historia aqui de forma rápida, vamo lá:
Ao trabalhar-mos com funções assíncronas no JavaScript temos alguns recursos bem comuns como utilizando callbacks, porem os callbacks podem causar o famoso callback hell.
Aí começamos a usar promises para resolver o problema do callback hell, porém se tivermos muitas promises temos que ficar aninhando funções com o .then().
Então surgiu o async/await que faz com que o JavaScript espere que a promise seja resolvida antes de continuar executando o código.
Uma função com async/await pode ser escrita da seguinte forma:
Perceba que temos a palavra async logo antes da declaração da arrow function que é atribuída a const “doSomething” e no corpo da função temos o await, que irá esperar a execução da promise “doSomethingElse”.
Nesse exemplo temos apenas o caminho perfeito, caso a promise “doSomethingElse” execute e seja resolvida (resolve). Caso algum erro ocorra e ela seja rejeitada (reject), não será tratado nessa função.
Tratando erros com Try/Catch
Agora vamos pegar o exemplo acima e tratar os erros com usando try/catch.
Agora teremos o console.log caso tudo ocorra bem e um console.error caso a promise “doSomethingElse” seja rejeitada. Mas escrever dessa forma torna o nosso código muito verboso, imagina ter que fazer um try/catch pra cada função assíncrona que a gente faz? Ai que entra o pulo do gato de capturar os erros de um async/await sem try/catch!
Destructuring salvando vidas
Ai que entra a mágica do destructuring. Se você não lembra o que é destructuring, ele nada mais é do que uma sintaxe nova do JavaScript para atribuir valores de arrays ou propriedades de objetos em variáveis destintas! Veja o exemplo abaixo:
Espero que o exemplo acima tenha esclarecido as coisas.Na linha 3, pegamos o array numbers e atribuimos às constantes a e b, recebendo respectivamente os valores 10 e 20.
Sabendo disso, podemos finalmente utilizar dessa técnica para tratar os erros do nosso async/await sem usar o try/catch.
Tchau Try/Catch
Agora podemos dar tchau para o try/catch. Não me entenda mau, não quero eliminar o try/catch de todo o meu código em todos os meus projetos, estou apenas apresentando uma abordagem, onde podemos tratar os erros de uma chamada async/await sem usar o try/catch.
Para isso vamos criar uma função helper que irá englobar nossa promise. Vamos chamar essa função apenas de “to()”. Ela irá receber a promise a ser executada como parâmetro e sempre retornará um array de 2 posições, onde a primeira posição é o erro e a segunda posição o resultado.
Ela ficará dessa forma:
A função “to”, que você vai entender o motivo desse nome mais a frente, serve apenas para englobar a nossa promise. é uma função bem simples que você pode reutilizar sempre que necessário.
Agora vamos aplicar a função “to” em nosso exemplo inicial.
No exemplo o nome “to” começa a fazer mais sentido, deixando a leitura do código de forma clara, “await to doSomething”.
E caso tenha o erro, chamamos a console.log e em seguida retornando. Vale lembrar que geralmente teríamos apenas o “if(error) return;”
Esse é uma forma bem criativa de tratar essa situação. Discutivelmente pode ser algo que muitos acharão ótimo e outros acharão horrível, mas tudo é uma questão de preferencia de “code style” de cada um. Lembrando que se você trabalha com os hooks do React, você está acostumado com esse tipo de método que sempre retorna um array de duas posições. Tipo os callbacks que por convenção sempre recebem o erro no primeiro parâmetro e o resultado no segundo.
Obrigado pela leitura, compartilhe!
Se você gostou desse post, compartilhe com seus amigos, ajude a espalhar conhecimento!
- Faça parte da nossa lista de Desenvolvedores ?
- Se inscreva em nosso canal do Youtube ?
- Curta nossa página no Facebook ?
- Não perca as atualizações no Twitter ?
- Veja as dicas no Instagram ?
- Siga nossos repositórios no Github ⌨️
Photo por Wil Stewart no Unsplash
3 Comments
Claudio Lazaro · 2020-04-20 at 17:59
Good Explanation !
Cledimir Silva · 2020-06-22 at 14:48
Muito bacana o code style…
Abner Matheus · 2020-09-29 at 14:58
(node:7108) UnhandledPromiseRejectionWarning: TypeError: Invalid attempt to destructure non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.