0

Im working with node.js, Mongoose and the Q library for promises (https://github.com/kriskowal/q/wiki/API-Reference)

I was wondering what's the difference between:

var Kitty = mongoose.model("Kitty");
var findKitties = Q.nbind(Kitty.find, Kitty);

findKitties({ cute: true }).done(function(theKitties) {
    console.log(theKitties);
});

and this:

var Kitty = mongoose.model("Kitty");
var query = Kitty.find({ cute: true });
Q(query.exec()).done(function(theKitties) {
    console.log(theKitties);
});

They both work, but which one is better? Are they the same?

Thanks

davibq
  • 1,089
  • 11
  • 31

1 Answers1

2

Take a look at the Mongoose documentation for exec() and you will see:

aggregate.exec(callback);

// Because a promise is returned, the `callback` is optional.
var promise = aggregate.exec();
promise.then(..);

In other words, Mongoose's exec can follow node callback style or use promises.

The first example you provided, Q.nbind() assumes that exec uses node callbacks. In your second example Q() assumes that whatever passed into it is either a promise or a value.

The only reason both methods work is because Mongoose has implemented both node callbacks, and promises. This usually isn't the case!


Because Mongoose already supports promises natively, go for

var query = Kitty.find({ cute: true });
Q(query.exec()).done(/* ... */);

instead of wrapping the node style callbacks:

var findKitty = Q.nbind(Kitty.find, Kitty);
findKitty({ cute: true }).done(/* ... */);

To answer a question in the comments:

do you have any information on update and delete?

take a look at the queries documentation:

When a callback function:

  • is passed, the operation will be executed immediately with the results passed to the callback.
  • is not passed, an instance of Query is returned, which provides a special QueryBuilder interface for you.

So basically it's possible to do something like this:

var query = Kitty.update({ cute: false }); // :(
query.exec().then(/*  */)

instead of using nbind:

var updateKitty = Q.nbind(Kitty.update, Kitty);
updateKitty({ cute: false }).then(/*  */)

Both will work, it's up to you if you want to execute the update at that moment by using a callback, or in another line using exec. Read that documentation for more information.

Jay
  • 18,959
  • 11
  • 53
  • 72
  • Thanks for the answer.. Just for the record, do you have any information on update and delete? I think they do need to use nbind right? – davibq Feb 10 '14 at 21:59
  • Glad to help. I've updated my answer - I've never used Mongoose so I've had to do some looking around. – Jay Feb 10 '14 at 22:29
  • Updated the first example. Basically build a query be it `Kitty.find` or `Kitty.update` and then call `.exec` to run that query and get back a promise. – Jay Feb 10 '14 at 22:34