How To Perform Asynchronous Calls in Parallel, Serially or with Throttling in NodeJS using Async
If you are familiar with the concept of asynchronous programming, you must have come across scenarios where you need to loop over asynchronous calls. For example, you need to get email ids of all users related to a project with ID Proj_ID
for sending a report.
user1 --> email1
user2 --> email2
.
.
useri --> emaili
Now, considering all your users are stored in a database and getting email Ids of all the users related to Proj_ID
will be an asynchronous call to the database. You need to ensure email Ids of all users have been fetched before initiating mail sending. One of the best ways of doing this is via a node module called async
:
Using Async Library
For using Async module:
npm install async --save
This will add async to your node modules. Now, you can include it in the file you wish to use as:
var async = require('async');
Once, you have all the users, you can find their IDs and create an array of emails which can be used by you mailService for sending the report. Here is a snippet for the same:
var emails = [];
async.each(userIDs, function(userID, callback) {
UserService.getUserFromID(userID, function(err, user) {
if (err || !user) {
console.log(err);
// Even in case of error, don't forget to call the callback
callback();
} else {
email.push(user.email);
callback();
}
}) },
function(err) {
if (err) {
console.log(err);
} else {
MailService.sendReportEmail(emails);
}
});
}
});
In the snippet above, async.each
will take an array of userIDs and initiate asynchronous calls for all userIDs. Once the DB call for a user is finished, it will call callback
function which ensures that async has completed action for that particular user. Once, callback
is called for all the users, and there has been no error, it will call the final callback which in our case callsMailService.sendReportEmail
on the email array. You need to remember to call a callback() in error function as well else async
would not be able to exit and will be stuck waiting for all DB calls to be finished.
Also, if you call callback
with error like callback(error)
it will pass that error to the final callback. Depending on the severity of the error you can go ahead or abort the operation you want to do in the final callback.
This is what is happening visually here, each callback is called in parallel here, and each may finish at different times, however, the final callback will only be called when all the callbacks are finished.
You can read about Async in details here.
How much is a great User Experience worth to you?
Browsee helps you understand your user's behaviour on your site. It's the next best thing to talking to them.