Michael Irwin
Michael Irwin

Reputation: 3149

Node using promises in conjunction with async module

I'm using the async module to help with creating an object that depends on other objects that are created asynchronously. The asynchronously created objects have validations that are ran against them that ultimately return a promise. The problem I'm having is that the "final" async callback seems to never be called and I cannot figure out why.

Example code:

function construct(self, opts) {
  async.parallel({
    venue: function(callback) {
      new Venue(opts.venue).then(function(venue) {
        callback(null, venue);
      }).catch(function(err) {
        callback(err);
      });
    },
    artists: function(callback) {
      new Artist(opts.artist).then(function(artist) {
        callback(null, artist);
      }).catch(function(err) {
        callback(err);
      });
    },
    function(err, res) {
      console.log(res);  // THIS IS NEVER CALLED.
    }
}

Upvotes: 1

Views: 661

Answers (1)

Retsam
Retsam

Reputation: 33439

It looks like the issue is that your callback function is inside the object that you're passing to async.parallel instead of as its own argument.

You've got

 async.parallel({
      venue: func,
      artists: func,
      callback
 })

Instead of

async.parallel({
      venue: func,
      artists: func,
      }, callback
);

BUT, it's really worth questioning what you gain from mixing promises and async like this; they're essentially designed to accomplish the same task; it'd probably be worth picking one or the other. Something like Promise.all or Promise.join is an alternative to async.parallel.

Pure promise version of this would look like: (this is assuming bluebird promises; but other libraries would be similar, if not identical)

Promise.join(new Venue(opts.venue), new Artists(opts.artists))
.then(function(venues, artists) {
    //
});

That's a lot cleaner, I think.

Upvotes: 2

Related Questions