Mongoose和promise:如何获得一个查询结果数组?

使用mongoose从db和Q中查询promise的结果,但发现很难绕过我的头,只是得到一个可用的用户列表。 目前我有这样的一些东西:

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 ) 

SomeOtherFunction之前如何完成查询,而不做大量的马虎callback?

另一个build议是使用MongoDB的$in操作符传入一个数组,以便高效地find并获取大量结果。 每个将是一个mongoose对象。

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

这比提出多个请求更有效率,每个_id一个请求。

“如何继续承诺”这个问题的答案几乎总是与。 这是诺言的比喻; 并终止一个asynchronous语句。 您可以返回承诺,并在继续之前拆包。

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

或者干脆Q.all(promise).then(SomeOtherFunction)

您还需要findOne来实际返回承诺。 您可以使用调用节点函数的Q.nfcall ,也可以使用Q.nfcall

Q.all所做的就是接受一系列的承诺,当他们中的一个拒绝时拒绝。 如果任何查询失败或者使用.done来表示链的末尾,您可能需要附加.catch处理程序。 像Bluebird这样的其他承诺库,即使没有.done或添加一个显式处理程序,也会为你挑错,可惜Q不这样做。

你也可以用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); });