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.

Top comments (0)