Underscore is a utility library that provides some useful features like each , map and reduce . But they all work synchronously. for instance
var results = _.map([1,2,3], function(value, index, list) { return value * 2; }); console.log(results);
Conclusion: [2, 4, 6]
If you notice, the console.log(results) statement is called only after the _.map() function has _.map() and the results are returned. This is a typical synchronous programming style that you use in browser scripts.
On a server where Node.js is king, synchronous programming, as described above, is detrimental to the event loop. There, preference is given to the asynchronous programming style. Take a look at the same map method using the async library.
async.map([1,2,3], function mapper(item, callback) { callback(null, item * 2); }, function(error, results) { console.log(results); } );
Conclusion: [2, 4, 6]
If you notice, it does not return the displayed array as a return value, instead, the associated array is passed to the callback function, and console.log(results) used to print the results inside the callback.
One of the side effects of this programming style is that the iterator function is called in parallel, not in sequential order, thereby providing greater scalability if the iterator function uses any I / O.
So, while some of the features offered by the async library are similar to those offered by Underscore , they are designed for different purposes, as shown above. Now the decision about which ones to use depends on your requirements and programming style.