async and Q promises in nodejs

dzm picture dzm · Dec 16, 2013 · Viewed 7.5k times · Source

I'm using the Q library and async library in nodejs.

Here's an example of my code:

async.each(items, cb, function(item) {

 saveItem.then(function(doc) {
    cb();
 });

}, function() {

});

saveItem is a promise. When I run this, I always get cb is undefined, I guess then() doesn't have access. Any ideas how to work around this?

Answer

Paul Mougel picture Paul Mougel · Dec 16, 2013

Your issue doesn't lie with promises, it lies with your usage of async.

async.each(items, handler, finalCallback) applies handler to every item of the items array. The handler function is asynchronous, i.e. it is handed a callback, that it must call when it has finished its work. When all handlers are done, the final callback is called.

Here's how you'd fix your current issue:

var handler = function (item, cb) {
  saveItem(item)
  .then(
    function () { // all is well!
        cb();
    },
    function (err) { // something bad happened!
        cb(err);
    }
  );
}

var finalCallback = function (err, results) {
  // ...
}

async.each(items, handler, finalCallback);

However, you don't need to use async for this particular piece of code: promises alone fill this job quite nicely, especially with Q.all():

// Create an array of promises
var promises = items.map(saveItem);

// Wait for all promises to be resolved
Q.all(promises)
.then(
    function () { // all is well!
        cb();
    },
    function (err) { // something bad happened!
        cb(err);
    }
)