One of the main issues you face when coming from a language like Java, as I did, is that most calls you make in Node are asynchronous. There is a single thread which is constantly making calls in the background, to which you provide callback handlers.
This is an easy enough concept to get - it means you get code like:
doMyThing(finished) {
// do some stuff
finished();
}
function finished() {
// called when doMyThing() is all done
}
But this gets compounded, and more and more complicated when, for instance, doing a lot of database calls that depend on each other. Or if you have several sets of processing that need to be done in order. You end up chaining endless callbacks, which makes the code incredibly hard to read.
There is no inherent thread management in Node (that I've discovered) so what do you do if you need control over the fork() and join() calls (to quote C / POSIX terminology).
The answer I found is the async module I found here: https://github.com/caolan/async
I think there are many people using this, and it's fab! It's so fab I'm now using it when I need asynchronous control, but actually I've replaced all my for() loops with async.each - thus:
Consider this simple loop to work on the results of a DB call:
db.sequelize.findAll({where: {criteria: someCriteria}}).success(function(results) {
// results will be provided from Sequelize as an array of objects populated from the db
// for-loop method:
for (var i = 0; i < results.length; i++) {
// do something with results[i];
}
// async.each method:
async.each(results, function(result, callback) {
// do something with result
// now tell the async library we're done with this result
callback();
}, function() {
// this optional function will be called when all the results have been processed
})
});
Forgive me if this doesn't quite have the right number of brackets and so on - I've not typed it in to check the syntax is 100%.
Note the difference - the for loop method iterates over the array, processing each element. The async.each method asynchronously calls the provided function for each element in the array, potentially calling a final method when all entries have returned. Note that the body of the handler function must contain a call to the provided callback function to tell the async library when this entry has been processed.
There are variations within the library to handle processing these in series (async.series) and a multitude of other useful things, so it has really become, for me, an essential module for programming in Node.