0

i am new to nodejs, and i am headache with callback..
i want to write an app that allow users to select and query some device status of the server (e.g. ping, cpu, memory, etc.). The items to be queried will be sent to the backend server though URL. I used a for loop and a switch to call the functions which execute shell commands (eg. ssh, ping, etc) to get server status. Finally i want to write all the result (res.write) to front end.
I failed to make it work, either return null or approach 'write before end' error... please help me. Here is my code, i tried to simplify it.

app.get('/check', function(req, res, next) {
    var selecteditems = req.query.selecteditems; //ping,memory,disks,etc. 
    checkcon(selecteditems, function(results) {
        res.write(JSON.stringify(results), function(err) {
            res.end();
        });
    });
});

var checkcon = function(selecteditems, callback) {
    var selecteditems = selecteditems.split(',');
    var allresults = [];
    selecteditems.forEach(function(entry) {
        switch (entry) {
            case "ping":
                checkping(function(results) {
                    allresults.push(results);
                });

                break;
            case "memory":
                checkmemory(function(results) {
                    allresults.push(results);
                });
                break;
            case "disks":
                checkdisks(function(results) {
                    allresults.push(results);
                });
                break;
            case "disks":
                break
            default:
        }
        callback(allresults);
    });
}

example of the one of the function for shell command:

var checkping = function(callback) {
    var pingstat = [];
        const child = exec('ping -c 1 -W 1 10.102.12.2',
            (error, stdout, stderr) => {
                if (error !== null) {
                    console.log(`exec error: ${error}`);
                    pingstat.push("Unable to ping machine");
                } else {
                    pingstat.push("OK");
                }
                callback(pingstat);

            });
}
1
  • 1
    checkping is an async function and you are calling callback before waiting for it to finish. You will need to return a promise for each iteration and use Promise.all to wait for all to finish, and then call the callback function. Commented Feb 5, 2018 at 10:44

2 Answers 2

1

Use async eachOf, in order to loop over an array and apply async function on each element :

var selecteditems   = selecteditems.split(',');
var allresults      = [];

async.eachOf(selecteditems, function(item, index, cb){

     switch (item) {
        case "ping":
            checkping(function(results) {
                allresults.push(results);
                return cb();
            });

            break;
        case "memory":
            checkmemory(function(results) {
                allresults.push(results);
                return cb();
            });
            break;
        case "disks":
            checkdisks(function(results) {
                allresults.push(results);
                return cb();
            });
            break;
        case "disks":
            return cb();
            break
        default:
            return cb();
     }

}, function(err){
   if(err)
   {
        // do stg
    }
    else
    {
         callback(allresults);
    }
})
Sign up to request clarification or add additional context in comments.

2 Comments

is async.eachOf same as async.forEachOf?
Yeah it's just an alias
1

You may use this method from async lib: https://caolan.github.io/async/docs.html#reduce

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.