문제

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

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));
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top