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"));
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) } }) }
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"); } );
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"));
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)