Nodejs — Tornando uma função assíncrona em uma função síncrona

Olá Gente!
Funções síncronas são excelente ❤, porem, em muitos casos não temos esta opções.
Para este tutorial, iremos executar um “Ping” utilizando a função “child_process” no Nodejs.
A função “child_process” é uma função assíncrona que possui alguns manipuladores que indicam cada mensagem enviada, algum erro e a conclusão do comando.
No exemplo abaixo estamos fazendo um Ping para a Google:
var CmPing = spawn('ping', ["google.com.br"]);
var TmpOut = "";
CmPing.stdout.on('data', (data) => {
TmpOut += data.toString();
});
CmPing.stderr.on('data', (data) => {
console.log("error", data);
});
CmPing.on('close', (code) => {
if( code === 0 )
{
console.log("sucesso", TmpOut);
}else{
console.log("error", code);
}
});
No exemplo acima estamos executando o Ping e manipulando cada mensagem, erros e o final do comando.
Porem, esta função ocorre em paralelo a todas as outras já em execução.
Por exemplo, temos o código abaixo onde estamos fazendo um “console.log” antes e depois do Ping:
console.log(">> Antes do Ping <<");
[Ping Aqui]
console.log(">> Depois do Ping <<");O resultado é:
Observe que os dois “console.log” são executados e só quando o ping termina que seu resultado é exibido.
Porem, imagine que precisamos do retorno do ping para executar a função seguinte, esta alternativa se tornaria inviável.
Para este caso, o ideal seria utilizar uma função sincronia, utilizando o async/await.
Mas como iremos transformar esta função em uma função assincrona?
Para isto iremos utilizar o “Promise”, que basicamente é uma “Promessa” de que algo ira ser retornado em algum momento.
O promise faz com que o que estiver dentro do promise possa enviar um “resolve” indicando que a função foi finalizada e o “reject” indiando um falha.
Vamos adaptar o Ping para uma função sincrona:
const ping = async function(Host){
return new Promise((resolve, reject) => {
var CmPing = spawn('ping', [Host]);
var TmpOut = "";
CmPing.stdout.on('data', (data) => {
TmpOut += data.toString();
});
CmPing.stderr.on('data', (data) => {
reject(data);
});
CmPing.on('close', (code) => {
if( code === 0 )
{
resolve(TmpOut);
}else{
reject(code);
}
});
});
};
Veja que estamos criando um promise, e no manipulador “close” estamos enviando o “resolve” com tudo que o Ping retornou.
Agora basta chamarmos esta nova função com await:
const init = async function(){
console.log(">> Antes do Ping <<");
try {
const RetPing = await ping("google.com.br");
console.log(RetPing);
} catch(err) {
console.log(err);
}
console.log(">> Depois do Ping <<");
};
init();Após isto, teremos o seguine retorno:

Veja que o segundo “console.log” só é chamado quando a função “ping” finalizar.
E assim terminamos, pessoal! 👩💼
Até a próxima! 👋
Leia também
ClickHouse: instalando na VPS e usando com Node.js
Como instalar o ClickHouse numa VPS Ubuntu, proteger com senha, criar uma tabela de acessos e consultar 10 milhões de linhas pelo Node.js.
Avaliando o RAG com o Jev como juiz
Como dar nota ao seu RAG em Node.js: um gabarito, a busca do Qdrant medida sem IA e o Jev, da TypeSafe, dizendo se cada resposta é fiel e correta.
Pensieve: notas com API, MCP e Skill para a sua IA
Como funciona o Pensieve, app gratuito de notas com lembretes, e como usar a API REST, o servidor MCP e a Skill para a sua IA anotar por você.


