[ Conteúdo ] Funções Assíncronas
Introdução:
Boa noite pessoal! Fazia um tempo que eu não aparecia, e recentemente tive uma ideia sobre um curto artigo sobre funções assíncronas no JavaScript, que é um tópico bastante importante dado a quantidade de posibilidades que Promises
nos proporciona na linguagem e seus derivados como fetch
e assim por diante.
Bom, não sei se tem algum artigo sobre aqui (perdão por não procurar antecipadamente). Se existir, encare isso como minha versão sobre o assunto. Dito isso, vamos para o que interessa.
Considerações:
Naturalmente, você deve dominar toda a base do JavaScript
, em especial entender como Promises
e functions
se comportam na linguagem.
Além disso, farei breve menções sobre tipagem, ou seja, envolve um pouco de TypeScript
, mas nada muito complexo.
O que são funções assíncronas?
O nome por si só já é bem sugestivo: São funções que lidam com operações assíncronas. Funções assíncronas nos permite escrever de maneira elegante e clara operações assíncronas ou lidar com operações assíncronas externas (retornada por outras funções).
Não é difícil criar uma função assíncrona, basta utilizar a palavra chave async
antes da palavra chave function
. Confuso? Então um breve exemplo:
async function MinhaFuncaoAssincrona() {
//...
}
Agora, tudo que eu faço dentro desde escopo se comporta como uma Promise
? A resposta é, não exatamente...
Assim como tudo na área de tecnologia, nada é tão simples assim, mas não é tão difícil, apenas existe o jeito certo de fazer as coisas. Funções assíncronas não param por aqui, tem mais features que ajudama a ter um comportamento melhor.
Mas, se você quer apenas um retorna de uma Promise
, então sim, o código acima retorna uma Promise
e mais abaixo eu explico em detalhes.
Palavra chave await
:
Quando declaramos uma função assíncrona, nos é permitido a utilização da palavra chave await
dentro de seu escopo.
E para que serve o await
, bom, aqui é que entra a mágica! A palavra chave await
basicamente diz que as operações abaixo devem esperar a operação que tem um await
para pode continuar. Confuso? O comportamento é igual ao padrão do JavaScript, ou seja, parece síncrono.
Então vamos tentar ilustrar melhor com um exemplo usando 2 fetch
:
const myFetch1 = fetch('url1');
const myFetch2 = fetch('url2');
async function MinhaFuncaoAssincrona() {
const first = await myFetch1.then(result => result.json());
const second = await myFetch2.then(result => result.json());
}
Acima, temos 2 fetch
que retornam uma Promise
, ou seja, uma operação de natureza assíncrona. Dento da função assíncrona, temos duas constante que convertem os resultados do fetch
para json
, mas aqui, a ordem é deterministica.
A constante second
vai esperar a constante first
para poder converter para json
. Simples, não? A operação ainda é assíncrona. Seu programa ou site não vai parar até esse primeiro fetch
ser convertido, apenas dentro deste escopo, dentro desta função assíncrona, controlamos a ordem das coisas.
Entender sobre concorrência
ajuda a entender com mais precisão sobre a ordem.
a ordem que os primeiro
fetch
são resolvidos é não deterministica. O que isso quer dizer? Quer dizer que não temos como saber qual vai ser resolvido primeiro. Entranto, oawait
controla a ordem em que eles são convertidos.
Sem await, não é assíncrono:
Na documentação deixa bem claro que uma função assíncrona, que não tenha nenhum await
nela é executada de forma síncrona:
async function HandleClick() {
// está função não é executada de forma assíncrona.
}
Além disso, você pode ter qualquer quantidade de await
em funções assíncrona, até zero, que cai no caso acima.
Funções assíncronas sempre retornam promises:
Sim, isto aqui é bem interessante. Independemente se o valor retornando não for uma Promise
, o valor será embrulhado em uma Promise
:
async function HandleMyAge(age) {
return age;
}
HandleMyAge(22) // Promise<number>
Isto aqui é mais evidente no TypeScript
, por isso que nunca usou pode não entender muito bem o que é Promise<number>
. Apenas saiba que é uma Promise
do tipo number
, de forma resumida 😄
Voltando ao assunto: Funções assíncronas sempre retornam uma Promise
, mesmo quando não tem um return
explicitamente declarada. Funções que não tem return
, não retornam nada, ou seja, tem o tipo de retorno definido para void
. Entretando, em funções assíncronas, até esse void
é embrulhado em uma promise:
async function HandleVoid() {
// retorna Promise<void> que resolve para `undefined`
}
Isso pode abrir algumas possibilidades, pois mesmo resolvendo para undefined
, você pode encadear com o then
, dando que no fim, é uma Promise
.
async function HandleVoid() {
// retorna Promise<void> que resolve para `undefined`
}
HandleVoid()
.then(() => console.log("fazer algo"))
.then(() => console.log("fazer outra coisa"))
Conclusão:
EU diria que é um bom conteúdo introdutório sobre funções assíncronas, não? Na verdade, basicamente se resume a isto ai, não tem nada mais técnico sobre, além de técnicas em que funções assíncronas estão envolvidas ou nuances que diferem de caso para caso.
Então é isso, espero que tenham gostado.