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

最后都变了- 提交于 2019-12-04 08:08:41

问题


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?


回答1:


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.




回答2:


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.




回答3:


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);
});



回答4:


Using Promise API could be an option here:

const arrayFullOfPromises = [];
arrayFullOfPromises.push(mongooseModelA.find({_id: aId}).exec());
arrayFullOfPromises.push(mongooseModelB.find({_id: bId}).exec());
Promise.all(arrayFullOfPromises).then(results => console.log(results));


来源:https://stackoverflow.com/questions/22794827/mongoose-and-promises-how-to-get-an-array-of-query-results

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!