Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct way of using Bluebird for Mongoose promises?

I've been reading documentaion and articles and everyone seems to describe a different way about using Mongoose and Bluebird together. Even the official Mongoose documentation says something and Bluebird documentaion says another thing.

According to Mongoose:

mongoose.Promise = require('bluebird');

According to Bluebird:

var Promise = require("bluebird");
Promise.promisifyAll(require("mongoose"));

So to my understanding, if you pick the Mongoose way a sample query would be like:

User.findById('someId')
    .then(function(){
        // do stuff
    })
    .catch(function(err){
        // handle error
    })

But also in Mongoose docs it says that:

Mongoose queries are not promises. However, they do have a .then() function for yield and async/await. If you need a fully-fledged promise, use the .exec() function.

So in this case, is .then above a promise or not?

If you go with Bluebird way:

User.findById('someId')
    .execAsync()
    .then(function(){
        // do stuff
    })
    .catch(function(err){
        // handle error
    })

Or maybe even skip execAsync() and start with findByIdAsync instead.

Really confused with different documentaion. I'd appreciate if someone can shed some light into this.

like image 964
Özgür Uysal Avatar asked Nov 11 '16 15:11

Özgür Uysal


2 Answers

Choose the Mongoose way:

mongoose.Promise = require('bluebird');

That's because Mongoose already supports promises (besides also accepting callbacks); the above code just replaces Mongoose's own promise library (mpromise) by Bluebird (which is probably faster, better tested, and has more utility functions available).

Bluebird's promisify*() is meant to allow code that doesn't already use promises (purely callback-based functions) to return promises.

like image 93
robertklep Avatar answered Oct 05 '22 10:10

robertklep


From Bluebird doc

Promise.promisifyAll(
    Object target,
    [Object {
        suffix: String="Async",
        multiArgs: boolean=false,
        filter: boolean function(String name, function func, Object target, boolean passesDefaultFilter),
        promisifier: function(function originalFunction, function defaultPromisifier)
    } options] ) -> Object

as you can see, by default, promisifyAll add suffix 'Asyns', so if you are using this way of promisification:

var Promise = require("bluebird");
Promise.promisifyAll(require("mongoose"));

the async version of User.findById will be User.findByIdAsync

what about mongoose.Promise

then you use promise library like

mongoose.Promise = require('bluebird');

built-in promise mechanism replaced by library: query.exec().constructor replaced by require('bluebird') so instead .exec() for return promise, you can use bluebird probabilities directly for mongoose queries like

User.findOne({}).then(function(user){
    // ..
})  
like image 35
stasovlas Avatar answered Oct 05 '22 11:10

stasovlas