BadKnees
BadKnees

Reputation: 149

How to know when finished

Im pretty new to node.js, so i'm wondering how to know when all elements are processed in lets say:

["one", "two", "three"].forEach(function(item){
    processItem(item, function(result){
        console.log(result);
    });
});

...now if i want to do something that can only be done when all items are processed, how would i do that?

Upvotes: 6

Views: 2489

Answers (3)

Buğra Ekuklu
Buğra Ekuklu

Reputation: 3278

Albeit other answers are correct, since node.js supports ES6 henceforth, in my opinion using built-in Promise library will be more stable and tidy.

You don't even need to require something, Ecma took the Promises/A+ library and implemented it to the native Javascript.

Promise.all(["one", "two","three"].map(processItem))
  .then(function (results) {
    //  here we got the results in the same order of array
} .catch(function (err) {
    //  do something with error if your function throws
}

As Javascript is a adequately problematic language (dynamic typing, asynchronous flow) when it comes to debugging, sticking with promises instead of callbacks will save your time at the end.

Upvotes: 1

silijon
silijon

Reputation: 942

forEach is blocking, see this post:

JavaScript, Node.js: is Array.forEach asynchronous?

so to call a function when all items are done processing, it can be done inline:

["one", "two", "three"].forEach(function(item){
    processItem(item, function(result){
        console.log(result);
    });
});
console.log('finished');

if there is a high io-bound load for each item to be processed, then take a look at the module Mustafa recommends. there is also a pattern referenced in the post linked above.

Upvotes: 1

Mustafa
Mustafa

Reputation: 10413

You can use async module. Simple example: The

async.map(['one','two','three'], processItem, function(err, results){
    // results[0] -> processItem('one');
    // results[1] -> processItem('two');
    // results[2] -> processItem('three');
});

The callback function of async.map will when all items are processed. However, in processItem you should be careful, processItem should be something like this:

processItem(item, callback){
   // database call or something:
   db.call(myquery, function(){
       callback(); // Call when async event is complete!
   });
}

Upvotes: 6

Related Questions