I'm migration a project from Q to bluebird. In this project Q.invoke is used a lot.
e.g. in central methods like this:
repo.count = function(entity,query) { // entity is a mongoose model
var command = query = entity.find(query).count();
return Q.ninvoke(command, 'exec');
};
What would be the best bluebird way of refactoring this code and returning the same "kind" of promise? Reading the bluebird docs, it seems that promisifyAll seems to be the point in the right direction. Right now I have this which works, but makes the call blocking:
repo.count = function*(entity,query) {
entity = bluebird.promisifyAll(entity); // this needs to be moved somewhere central
return yield entity.find(query).count();
};
Well, there are several things you can do. The most obvious is surprisingly "nothing".
Mongoose already returns Promises/A+ promises when you don't pass exec its callback, you can just assimilate them:
repo.count = function(entity,query) { // entity is a mongoose model
return entity.find(query).count().exec(); // return promise
};
You can safely use that promise with Bluebird which will assimilate it gladly:
Promise.resolve(repo.count(e, q)); // convert to bluebird promise explicitly
someOtherBBPromise.then(function(query){
return repo.count(entity, query); // `then`able assimilation
});
That said, it can be desirable to have bluebird promises all-over. For this bluebird has a very robust promisifyAll
that lets you promisify mongoose at once:
var Promise = require("bluebird");
var mongoose = Promise.promisifyAll(require("mongoose"));
// everything on mongoose promisified
someEntity.saveAsync(); // exists and returns bluebird promise