Shamoon
Shamoon

Reputation: 43569

Using bluebird Promises, how can I do a nested each?

I have 2 arrays and I want to do something to each combination of them. For example:

var array1, array2;

array1 = [1, 2, 3];

array2 = [4, 5, 5];

async.each(array1, function(val1, cb1) {
  return async.each(array2, function(val2, cb2) {
    return doProcessing(val1, val2, function(err) {
      return cb2(err);
    });
  }, function(err) {
    return cb(err);
  });
}, function(err) {
  return console.log('DONE');
});

How can I do this with bluebird Promises?

I am using the async module here because doProcessing is an async call.

Upvotes: 2

Views: 897

Answers (1)

Benjamin Gruenbaum
Benjamin Gruenbaum

Reputation: 276406

First of all about doProcessing promisify it:

process = Promise.promisify(doProcessing);

There is no sense in working with callbacks in this case if you already have bluebird included. Now it returns a promise and you can easily work with it. As for the other part of the question you need all pairs - you can refactor that to an async nested for loop:

return Promise.each(array1, function(val1){
     return Promise.each(array2, function(val2){
          return process(val1, val2);
     });
}).then(function(){
    // all done
});

Note that if the arrays contain just numbers do a normal loop rather than promises - each is useful here in case the values are themselves obtained from an async source.

Alternatively - here is a more functional way with Ramda:

var all = Promise.all.bind(Promise);
var wait = R.compose(all, R.map(all), R.xprod);
wait(arr1, arr2).map(R.apply(process));

Upvotes: 3

Related Questions