Mongoose and promises: how to get an array of query results?

The answer of the question "how do I continue with promises" is almost always with .then. It is the promise analogy of ; and it terminates an asynchronous statement. You can return promises in it and it will unwrap them before continuing.

Q.all(promises).then(function(users){
    SomeOtherFunction(users);
});

Or simply Q.all(promise).then(SomeOtherFunction)

You would also need findOne to actually return promises. You can either use Q.nfcall which calls a node function or promisify it yourself.

What Q.all does is accept an array of promises and fulfills when all of them do and rejects when one of them rejects. You might want to append a .catch handler in case any of the queries fail or use .done in order to signify the end of a chain. Other promise libraries like Bluebird will pick up errors for you even without .done or adding an explicit handler, sadly Q doesn't do this.


Another suggestion would be to use MongoDB's $in operator to pass in an array to find and get a large set of results efficiently. Each will be a Mongoose object.

var promise = people.find({ _id: { $in: someArrayOfIds }).exec();
promise.then(function(arrayOfPeople) {
  // array of people ... do what you want here...
});

This would be far more efficient than making multiple requests, one for each _id.


You could also use q (npm install q)

var q = require('q')
, aPromise = mongooseModelA.find({_id: aId}).exec()
, bPromise = mongooseModelB.find({_id: bId}).exec();

q.all([aPromise, bPromise]).then(function(bothA_and_B) {
  console.log(bothA_and_B);
});