Olá, Web Developers!
Vamos falar hoje sobre a possibilidade de criar funções assíncronas e como trabalhar com elas de forma bem simples com as novas instruções async e await do JavaScript.
Vamos imaginar a seguinte situação:
function func1(number){
return new Promise(resolve =>{
setTimeout(() => resolve(77 + number) , 1000)
})
}
function func2(number){
return new Promise(resolve =>{
setTimeout(() => resolve(22 + number) , 1000)
})
}
function func3(number){
return new Promise(resolve =>{
setTimeout(() => resolve(14 * number) , 1000)
})
}
// Usando as funções
func1(4)
.then(number => {
console.log('Hello');
return func2(number);
})
.then(number => {
console.log('World');
return func3(number);
})
.then(result => console.log(result))
Usar essas funções assíncronas com Promises nos poupam do “Callback Hell”, mas mesmo assim, precisamos passar uma função de Callback para cada then().
Com async e await podemos trabalhar com código assíncrono em um estilo mais parecido com o bom e velho código síncrono. Vamos reescrever o exemplo anterior, partindo da parte onde consumimos as nossas três funções assíncronas:
async function myAsyncFunction(){
var number = await func1(4);
console.log('Hello');
number = await func2(number);
console.log('World');
var result = await func3(number);
console.log(result);
}
Primeiro de tudo, temos o comando async. Ele faz com que uma função automaticamente retorne uma Promise. Então:
// retorna o número 5
function example1(){
return 5;
}
// retorna uma Promise com o valor 5
function example2(){
return Promise.resolve(5);
}
// faz exatamente o mesmo que a função "example2()"
async function example3(){
return 5;
}
Depois, dentro de myAsyncFunction(), veja que usamos o comando await antes de chamar as funções que retornam Promises:
async function myAsyncFunction(){
var number = await func1(4);
Veja que, ao invés de usar o then() com uma função de callback, nós simplesmente estamos jogando o retorno da função em uma variável, como fazemos com códigos síncronos.
O comando await basicamente pausa a função myAsyncFunction() até que a Promise dentro da função func1() seja resolvida. Então o valor retornado é atribuído à variável e o código de myAsyncFunction() continua de onde parou.
Lembre-se: o comando await só pode ser executado dentro de uma função marcada como async. Por isso que para executar as funções eu criei a função myAsyncFunction().
Como estamos falando de funções assíncronas, não pense que essa “pausa” que o await causa irá travar o seu código todo. Lembre-se que essa é só uma nova sintaxe para se trabalhar com Promises. Então, quando o await pausar a sua função, outras funções poderão estar sendo executadas.
Curso JavaScript Intermediário
Conhecer o cursoDevo usar Async / Await ao invés de then()?
Isso vai depender muito da situação. Muitos desenvolvedores vão pelo gosto, outros definem um padrão único a se seguir para o projeto e outros decidem o que é melhor para cada caso.
Em meus projetos eu prefiro usar o que irá permitir uma melhor leitura e entendimento do código. No exemplo lá em cima, vimos um caso em que usar as funções com await deixou o código mais legível do que ficar criando vários then() (apesar de sempre atribuir o valor na mesma variável).
Vamos a um exemplo em que o then() pode deixar nosso código mais legível:
function example1(){
return func1(4)
.then(func2)
.then(func3);
}
async function example2(){
var number = await func1(4);
number = await func2(number);
number = await func3(number);
return number;
}
// ou
async function example3(){
return func3(await func2(await func1(4)))
}
O example2() e example3() usam o async/await. Veja que, nesse caso que só encadeamos funções, o uso do then() em example1() acaba sendo bem mais simples que example2() e mais legível que example3().
Sem contar que o comando await só funciona dentro de uma função async. Se estivermos dentro de uma função que não é async, teríamos que criar uma função async apenas para poder executar o comando await, enquanto as Promises podem ser usadas em qualquer lugar.
Concluindo
Async / Await aumentam as nossas possibilidades, mas também temos que analisar quando é o melhor momento para utilizá-los.
Os navegadores modernos e o Node.js já dão um bom suporte para eles, então, aproveite (com moderação)! ;)