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