DEV Community

Gabriel_Silvestre
Gabriel_Silvestre

Posted on • Edited on

Introdução ao Fluxo Assíncrono - Node.js

Tabela de Conteúdos


Callback

O que é?

É uma função que será executada por outra função, normalmente utilizada para controle de fluxo assíncrono.

O que faz?

Como dito em sua definição, é uma função que será chamada por outra função, dessa forma conseguimos preservar o fluxo do JS, permitindo que a própria linguagem faça o controle de chamadas, impedindo “travamentos” em operações de alta complexidade.

Sintaxe

Uma Callback é uma função que deve ser passada como argumento para outra função, dessa forma a função que irá receber a outra por parâmetro fica responsável pela execução da Callback. Essa função pode ser uma função convencional, uma Arrow function ou até uma função anônima.

function myCallback(err, content) {};

fs.readFile('./myFile.txt', myCallback);
Enter fullscreen mode Exit fullscreen mode
const myCallback = (err, content) => {};

fs.readFile('./myFile.txt', myCallback);
Enter fullscreen mode Exit fullscreen mode
fs.readFile('./myFile.txt', (err, content) => {});
Enter fullscreen mode Exit fullscreen mode

A função de Callback também pode seguir um padrão de estruturação, no caso de callbacks para métodos nativos do Node, tem-se o padrão de parâmetros.

Onde temos dois parâmetros, no qual o primeiro refere-se a algum erro que possa ocorrer durante a execução e o segundo é o valor que esperamos conseguir.

Voltar ao topo


Promises

O que é?

É uma API nativa do JS desde o ES6, disponibilizando formas de se lidar com o sucesso e fracasso de operações assíncronas.

O que faz?

As Promises surgiram para resolver o problema de aninhamento de Callbacks (callback hell), deixando a leitura, e por consequência a manutenção, de códigos assíncronos mais fácil.

As Promises resolvem esse problema através da disponibilização de métodos para o tratamento de sucessos ou erros, esses métodos por sua vez irão executar uma Callback definida por nós.

A vantagem das Promises em relação aos aninhamentos de Callbacks é que não precisamos aninhar Promises, apenas concatená-las, dessa forma é muito mais fácil de entender o fluxo.

Sintaxe

Criação

Definimos uma Promise a partir de sua instância, new Promise(), e passamos por parâmetros uma Callback que deverá receber dois argumentos, o primeiro é a função que será chamada em caso de sucesso (resolve) e o segundo é a função que será chamada em caso de fracasso (reject).

Normalmente criamos a Promise dentro de outra função que irá "envelopar” ela e por conveniência a Callback passada a Promise costuma ser uma função anônima.

function myPromiseFunction() {
  const promise = new Promise((resolve, reject) => {
    if (/*condition to fail*/) reject(new Error(/*mensagem de erro*/);

    resolve();
  });

  return promise;
}
Enter fullscreen mode Exit fullscreen mode
function divide(num, divisor) {
  const promise = new Promise((resolve, reject) => {
    if (divisor === 0) {
      reject(new Error('Não é possível dividir por zero!'))
    }

    resolve(num / divisor);
  });

  return promise;
}
Enter fullscreen mode Exit fullscreen mode

Utilização

Para consumirmos uma Promise devemos utilizar os métodos .then() e .catch(), eles executam as funções de sucesso e falha, respectivamente. Dessa forma, se necessário, podemos concatenar diversos métodos .then(), substituindo assim o aninhamento de Callbacks.

Esses métodos esperam receber uma Callback que será executada assim que a Promise for resolvida, gerando um sucesso ou uma falha.

myPromiseFunction()
  .then(() => {})  // sucesso
  .then(() => {})  // sucesso
  .catch(() => {});  // falha (caso falhar)
Enter fullscreen mode Exit fullscreen mode
divide(4, 2)
  .then((resultado) => { console.log(resultado) })  // 2
  .catch(() => {});  // falha (caso falhar)
Enter fullscreen mode Exit fullscreen mode
divide(4, 0)
  .then((resultado) => { console.log(resultado) })  // sucesso
  .catch((err) => { console.log(err) });  // Não é possível dividir por zero!
Enter fullscreen mode Exit fullscreen mode

Voltar ao topo


Async/Await

O que é?

São palavras-chaves do JS que nos permitem trabalhar com código assíncrono com uma sintaxe similar a do código síncrono.

O que faz?

Nem sempre precisamos utilizar a API das Promises, algumas vezes simplesmente queremos somente resgatar um valor, ou realizar operações simples, nesses casos entra o async/await.

Utilizando o async/await na função seu retorno será uma Promise, porém não será necessária a utilização dos métodos .then() e .catch(), pois tanto o tratamento de erros, quanto a execução de ações são feitos dentro da própria função.

Sintaxe

A sintaxe para a utilização de async/await é extremamente simples e similar a sintaxe de uma função síncrona comum, a única diferença é a utilização da palavra reservada async, antes da definição da função e o uso do await nas funções/métodos que retornam Promises.

E o tratamento de erros em funções de async/await é feito através do bloco try/catch.

async myAsyncFunction() {
  try {
    await somePromise();
  } catch (err) {
    /*tratamento do erro*/;
  }
};
Enter fullscreen mode Exit fullscreen mode
async function divide(num, divisor) {
  try {
    if (divisor === 0) {
      new Error('Não é possível dividir por zero!');
    }

    return num / divisor;
  } catch (err) {
    console.log(err);
  }
}
Enter fullscreen mode Exit fullscreen mode

** Vale a observação. Podemos criar funções assíncronas mais complexas com async/await, assim como faríamos utilizando new Promise(), porém a API de Promise consegue fazer essa função melhor, pois permite definir de maneira mais simples e legível as Callbacks caso a caso.

Voltar ao topo


Links Úteis

Voltar ao topo

Top comments (0)