javascriptnode.jsasync-await

Waiting for a function to complete before executing the next step - Node.js


I am new to Node.js and currently learning about promises and await/async. I tried the below code but couldn't figure out how to make the code wait till the function hostping is finished. I have also tried promises but couldn't make it wait.

var ping = require('ping');
var hoststatus
var hosts = ['google.com'];

async function test()
{
  var connected = await hostping(hosts);
  console.log('connected--------------', connected)
  connected.then(function(hoststatus) {
    console.log('hoststatus--------------', hoststatus)
    if (hoststatus == 1) {
      console.log('faaaaaaaail-------------')
    } else {
      console.log('passssssssssssssssss-----------')
    }
  });
}

async function hostping(hosts) {
  console.log('hosts-----------', hosts)
  await hosts.forEach(async function(host) {
    await ping.sys.probe(host, async function(isAlive) {
      var msg = isAlive ? 'host ' + host + ' is alive' : 'host ' + host + ' is dead';
      console.log(msg);
      if (isAlive == 'false') {
        hoststatus = 1
      }
    });
  });

  return hoststatus;
}

test()

Solution

  • To do what you want, you should use the promise wrapper of ping and also for..of because forEach doesn't work with async.

    Below is modification of your code to get the flow working as you expected:

    const ping = require('ping');
    const hosts = ['google.com', 'yahoo.com'];
    
    async function test()
    {
      const status = await hostping(hosts);
    
        if (status) {
            console.log('All hosts are alive');
        } else {
            console.log('Some/all hosts are dead');
        }
    
    }
    
    function hostping(hosts) {
        let status = true;
        return new Promise(async function(resolve, reject) {
          for (const host of hosts) {
            const res = await ping.promise.probe(host);
            var msg = `host ${host} is ${res.alive ? 'alive' : 'dead'}`;
            console.log(msg);
            if (!res.alive) { status = false; }
          }
            console.log('all host checks are done, resolving status');  
            resolve(status);
        });
    }
    
    test()
    

    If you're interested in understand more about async, these are good posts to read: https://www.coreycleary.me/why-does-async-await-in-a-foreach-not-actually-await/

    https://itnext.io/javascript-promises-and-async-await-as-fast-as-possible-d7c8c8ff0abc