マングースを使用して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
の前にクエリを終了させるにはどうすればよいですか?
もう1つの提案は、MongoDBの$in
演算子を使用して配列をfind
に渡し、大量の結果を効率的に取得することです。それぞれがマングースオブジェクトになります。
var promise = people.find({ _id: { $in: someArrayOfIds }).exec();
promise.then(function(arrayOfPeople) {
// array of people ... do what you want here...
});
これは、_id
ごとに1つずつ複数のリクエストを行うよりもはるかに効率的です。
「約束をどのように続けるか」という質問の答えは、ほとんどの場合_.then
_です。これは_;
_の約束のアナロジーであり、非同期ステートメントを終了します。その中でpromiseを返すことができ、続行する前にそれらをアンラップします。
_Q.all(promises).then(function(users){
SomeOtherFunction(users);
});
_
または単にQ.all(promise).then(SomeOtherFunction)
実際にpromiseを返すには、findOneも必要になります。ノード関数を呼び出す _Q.nfcall
_ または 自分で約束する のいずれかを使用できます。
_Q.all
_が行うことは、約束の配列を受け入れ、それらのallが実行すると実行し、そのうちの1つが拒否すると拒否します。クエリのいずれかが失敗した場合に備えて_.catch
_ハンドラーを追加するか、チェーンの終わりを示すために_.done
_を使用することをお勧めします。 Bluebirdのような他のpromiseライブラリは、_.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);
});
Promise APIの使用は、ここでのオプションになる可能性があります。
const arrayFullOfPromises = [];
arrayFullOfPromises.Push(mongooseModelA.find({_id: aId}).exec());
arrayFullOfPromises.Push(mongooseModelB.find({_id: bId}).exec());
Promise.all(arrayFullOfPromises).then(results => console.log(results));