DEV Community

Cover image for [pt-BR] Convertendo callbacks em promises em JavaScript
Plínio Balduino
Plínio Balduino

Posted on

[pt-BR] Convertendo callbacks em promises em JavaScript

Primeiro de uma série de posts curtos com conhecimentos que podem ser úteis no dia a dia e quero compartilhar. Muitas vezes eles exigem um conhecimento prévio da ferramenta ou da linguagem.

Esses textos curtos serão publicados sob a tag #quick.

Existem situações em que você precisa fazer com que um código que foi pensado para ser executado assincronamente seja executado de forma síncrona. Ao usar promises, você faz isso com o uso da palavra chave await:

await algoAssincrono
  .then(succeeded => console.log("Uhu!"))
  .catch(failed => console.error("Deu ruim"));
Enter fullscreen mode Exit fullscreen mode

A execução do código vai aguardar até que a promise seja finalizada para só então prosseguir.

Quando você está escrevendo um código que exige um comportamento síncrono, como uma AWS Lambda ou o equivalente de qualquer outro fornecedor de Cloud, você precisa garantir que todos os processos terminaram de ser executados antes do retorno da função:

exports.handler = async (event) => {

  return await processoAssincrono(event)
    .then(response => {
      return {
        statusCode: 200,
        body: JSON.stringify(message: response)
      };
    })
    .catch(failure => {
      return {
        statusCode: 400,
        body: JSON.stringify(reason: failure)
      }
    })
}
Enter fullscreen mode Exit fullscreen mode

A função processoAssincrono trata o evento recebido pela Lambda e, caso esteja tudo certo, retorna um status HTTP 200 e um conteúdo que será consumido pelo client, ou um status HTTP 400 caso não esteja tudo certo, com o motivo pelo qual a requisição falhou.

O nosso exemplo processoAssincrono foi pensado para ser assíncrono. Talvez ele consulte um banco de dados, uma API, ou qualquer recurso que poderia causar o bloqueio do event loop, então essa decisão faz todo o sentido, mas dentro de uma Lambda nós precisamos que o processo seja finalizado para só então retornarmos um valor. Com o uso de await, só retornamos um valor depois que a promise terminar sua execução, garantindo que a execução seja síncrona.

Quando você usa um código feito com callbacks, não existe essa possibilidade:

assincronoComCallbacks(
  function(succeeded) { 
    console.log("Funcionou");
  }, 
  function(failed) {
    console.error("Deu erro");
  }
);
Enter fullscreen mode Exit fullscreen mode

Para resolver isso, podemos criar uma promise que só segue em frente quando os callbacks forem executados:

await new Promise((fulfill, reject) => {
  assincronoComCallbacks(
    succeeded => fulfill(succeeded),
    failed => reject(failed)
  });
})
.then(succeeded => console.log("Uhu!"))
.catch(failed => console.error("Deu ruim"));
Enter fullscreen mode Exit fullscreen mode

A função com callbacks continua sendo assíncrona, mas estará encapsulada numa promise, permitindo assim o uso de await, tornando o processo seja executado como se fosse síncrono.

Latest comments (0)