Using mongoose to query results from the db and Q for promises, but finding it hard to wrap my head around just getting a list of users that's available. Currently I have some something like this:
var checkForPerson = function( person ) {
people = mongoose.model('Person', Person)
return people.findOne({"_id": person }, function(err, doc) {
if (err) console.log(err)
if (doc !== null) {
return doc
} else {
console.log('no results')
}
})
}
var promises = someArrayOfIds.map(checkForPerson);
// this is where I would like to have an array of models
var users = Q.all(promises)
//this fires off before the people.findOne query above to users is undefined
SomeOtherFunction( users )
How would I go about having the queries finish before SomeOtherFunction
without doing tons of sloppy callbacks?
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
.
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.
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);
});
来源:https://stackoverflow.com/questions/22794827/mongoose-and-promises-how-to-get-an-array-of-query-results