[ 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
fetchsão resolvidos é não deterministica. O que isso quer dizer? Quer dizer que não temos como saber qual vai ser resolvido primeiro. Entranto, oawaitcontrola 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.