0

I have the following function:

 function retrieveNotifications(promotions) {
         promotions.forEach( function(promotion) {

             //find all notification groups that have to be notified
             db
               .Notification
                   .findAll()
                       .then(function (notifications) {
                           //some code that adds notifications to an object
                        });                       
         });         
  };

How can I restructure it to wait till all notifications are added to the object. I can't use .then because it would be called multiple times because of the forEach

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
MentalRay
  • 334
  • 1
  • 6
  • You should be using `Promise.map` instead of that `forEach`, so that you can return a promise for your result – Bergi Feb 28 '15 at 22:50

3 Answers3

0

I would suggest using the async library: https://github.com/caolan/async

Basically it would go something like this:

async.parallel([ 
  // tasks..
], 
function () {
  // this is the final callback
})
Vee6
  • 1,527
  • 3
  • 21
  • 40
0

You could use .spread() which is built into Sequelize/Bluebird:

https://github.com/petkaantonov/bluebird/blob/master/API.md#spreadfunction-fulfilledhandler--function-rejectedhandler----promise

Have your forEach build up an array of db.Notification.findAll() and return it. Then call .spread on the result. If you don't know the length of the array returned you can use the arguments object in the success callback.

Is it possible to send a variable number of arguments to a JavaScript function?

Now .spread() will wait until each element in the array has returned and pass you an array with all your Notification rows.

Community
  • 1
  • 1
Kevin Wu
  • 8,461
  • 5
  • 28
  • 28
0

You're looking for Bluebirds collection functions, specifically map, each or prop. They will allow you to iterate your promotions array with an asynchronous callback, and you get a promise back that automatically resolves only when all of them have finished.

In your case it would look like this:

function retrieveNotifications(promotions) {
    return Promise.map(promotions, function(promotion) {
        // find all notification groups that have to be notified
        return db.Notification.findAll(… promotion …);
    }).then(function(results) {
        // results is an array of all the results, for each notification group
        var obj = {};
        for (var i=0; i<results.length; i++)
            //some code that adds notifications to the object
        return obj;
    });
    // returns a promise for that object to which the notifications were added
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375