web-dev-qa-db-ja.com

マングースと約束:クエリ結果の配列を取得する方法は?

マングースを使用して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の前にクエリを終了させるにはどうすればよいですか?

11
user240993

もう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つずつ複数のリクエストを行うよりもはるかに効率的です。

19
WiredPrairie

「約束をどのように続けるか」という質問の答えは、ほとんどの場合_.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はこれを行いません。

5

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
Brian P Johnson

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));
0
Przemek Nowicki