javascriptasync-await

send ping async and report


i am trying to ping a group of ip addresses whether it is up or down . For the purpose i am using 3rd party NODE-PING (npm i ping) library. i have a group of ip blocks as it is below.

const hosts = [
    {
        type: 'office',
        block: '192.1.2',
    },
    {
        type: 'station',
        block: '192.1.3',
    }
]

and i have got another list which includes last part of ip address as below again.

const controlList = [
    {
        type: 'camera',
        end: '100'
    },

    {
        type: 'printer',
        end: '98'
    }
]

when i use async await syntax in for loops pings wait lots of time for each to process. but whenever i turn to .then() notation it responses faster.

(async function sendPing(hosts,controlList){
    for (const host of hosts) {
        for (const clist of controlList) {

            ping.promise.probe(host.block + '.' + clist.end).then(function(res){
                console.log(res.inputHost, res.alive);
            })
        }
    }
})(hosts,controlList);

i am trying to run code faster using async-await as it runs with .then notation.


Solution

  • Presumably you're awaiting on every iteration of the loop? Something like this:

    (async function sendPing(hosts,controlList){
        for (const host of hosts) {
            for (const clist of controlList) {
                const res = await ping.promise.probe(host.block + '.' + clist.end);
                console.log(res.inputHost, res.alive);
            }
        }
    })(hosts,controlList);
    

    As semantically implied by the use of await here, this waits for each individual operation. So the operations execute in serial, each one completing before the next one begins.

    It sounds like you want to start all of the operations right away and then await all of them in parallel instead. Promise.all() is for exactly that.

    For example:

    (async function sendPing(hosts,controlList){
        // invoke the operations
        const promises = [];
        for (const host of hosts) {
            for (const clist of controlList) {
                // add the promise to an array
                promises.push(ping.promise.probe(host.block + '.' + clist.end));
            }
        }
    
        // await the results
        const results = await Promise.all(promises);
    
        // display the results
        for (const res of results) {
            console.log(res.inputHost, res.alive);
        }
    })(hosts,controlList);
    

    You can of course do whatever you like with the results, this is just using your existing code as an example. The main point here is to first queue up all of the promises and then await them all, rather than awaiting each one individually.