Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between async.map or async.each with async.parallel?

I started working on a node project recently and have been using the async library a lot. I'm kind of confused as to which option will be faster. Using async.map on some data and getting its results or using async.each to iterate over an array of users and put their corresponding operation into an array of function calls which I execute using async.parallel.

like image 779
Mukul Raina Avatar asked May 14 '15 00:05

Mukul Raina


2 Answers

Similar to JavaScript's forEach, async.each takes three parameters, the first of which is an array to iterate over, and the second is a function to apply to each element of the array (which is the first parameter). The form of the second parameter is iterator(item, callback) where iterator is the name of the function, callback which is also a function, with the form callback(err) which is called once iterator is completed. (Note: "If no error has occurred, the callback should be run without arguments or with an explicit null argument.") The third parameter of async.each is a callback that is called after execution of all iterator functions, and like the callback of each iterator has the form callback(err).

Source


The following, for brevity, is the form for the arguments of async.map:

  • arr - An array to iterate over.
  • iterator(item, callback) - A function to apply to each item in arr. The iterator is passed a callback(err, transformed) which must be called once it has completed with an error (which can be null) and a transformed item.
  • callback(err, results) - A callback which is called when all iterator functions have finished, or an error occurs. Results is an array of the transformed items from the arr.

Source


Getting to the core of the answer to your question, async.map maps its first parameter to an array by calling iterator on each element of the array which is its first parameter, but async.map must return an array, whereas async.each does not. This is reflected in the second of the third parameter of async.map (I am referring to results), which must be an array. That is to say that in the simplest example,

async.map([1, 2, 3], function iterator(item, callback_it){ return 2*item; }, callback(err, results))

assuming you have already implemented callback_it and callback, then in the above example [2, 4, 6] will be passed as the second argument of callback

like image 143
Francesco Gramano Avatar answered Nov 18 '22 00:11

Francesco Gramano


which option will be faster

Don't worry. The difference will be negligible if apparent at all, and the dedicated async function are quite optimised. Don't even try to come up with your own ones.

Using async.map on some data and getting its results

If that is what you want to do, use map. It's right there for your to be used for this purpose, and is quite readable.

using async.each to iterate over an array of users and put their corresponding operation into an array of function calls which I execute using async.parallel.

Sounds like a bad idea. Mostly, "putting functions in an array" is a synchronous operation so you would't use async at all, but the native array forEach instead. Or rather, just

async.parallel(data.map(function(d) {
    return function(cb) {
        // do what needs to be done with d and pass cb
    };
}), function(err, results){ … });

But that looks very pointless (and hardly faster) than just using async.map directly.

like image 1
Bergi Avatar answered Nov 18 '22 02:11

Bergi