Async programming can be confusing, but most of the confusion can be eliminated if you keep in mind things like callbacks and then
will run at a later time, after the code block they're contained in has already finished.
Promise libraries, async
module, are all attempts to get more control over a program's flow. Here is a good article explaining different approaches, that really helped me understand things by seeing different alternative solutions to the same problem.
A couple of the other answers mention Q.all()
. This works well, if you already have an array of promises.
If you have an array of values, or promises, there is another library that makes this even easier, called bluebird
. It has a method called .map()
that you can use to start a promise chain with an array.
With this approach you don't need to call the asynchronous, promise-returning function, store the returned promise in an array, then pass that array to Q.all
. It saves you some steps.
So, assuming you have an array of just values:
var items = [0,1,2,3,4,5,6,7,8,9];
You can do something like the following:
Promise.map(items, function (item) {
return performAsyncOperation(item);
}, {concurrency: n})
.then(function(allResults){
// 'allResults' now contains an array of all
// the results of 'performAsyncOperation'
})
Note: For this to work as expected, performAsyncOperation
must return a promise
Also note the 3rd argument to Promise.map()
: {concurrency: n}
. With this option specified, bluebird will only allow n
operations to be performed at a time, which can be useful if you have a huge amount of items to process that would overwhelm the system if they were all kicked off at once (network connections, filehandles, etc).
Final note: Here is the bluebird API doc. It's extremely well written with lots of examples, and a great way to explore how promises can help make your life easier.
Hope it helps!!!