2016-11-16 3 views
0

listCollectionメソッドをmongodbで使用し、返された各コレクションをfindを使用してループしています。forループ内のネストされたasync dbコール、wait untilループが実行されました

問題は、私はループが行われているが、findが非同期であるため、私はすべてのfindコールバックが前に終了するまで「待つ」する方法を考え出すで立ち往生していた後response.jsonに戻りたいオブジェクトを構築するためにループを使用することですresponse.json()

var data = {}; 

database.listCollections({name: {$ne: 'system.indexes'}}).toArray(function(err, collections) { 
    if (err) return res.json({}); 

    for(i=0; i<collections.length; i++){ 
     var collection = collections[i].name; 

     database.collection(collection).find(query, limit) 
     .sort({"Date": -1}).toArray(function(err, docs){ 

      if (err) return res.json({ 
      }); 

       /* Do stuff with docs, push stuff to data */ 
     }); 
     /** Console shows blank **/ 
     console.log("Data " + i+ ": " + JSON.stringify(data)); 
    } 
    /** Response is blank.. **/ 
    res.json(data); 
}); 

問題を返すことfind() Sが行われる前に、ループのための道を返すことです。 JS/Node方法でこれをどう対処しますか?私は解決策をまとめてみることができますが、後で同様の問題が発生する可能性があります。

編集:実際にデータが見つかった場合は、console.log()のデータ内に実際に内容があることがわかります。

答えて

1

NodeJSバージョンでサポートされている場合はPromiseを使用できます。それ以外の場合はPromiseライブラリを使用してください。この場合、コードforをループしてPromiseを返す関数にループし、それらのすべての約束オブジェクトを配列にプッシュすることができます。ループ呼び出した後

Promise.all(promisesArray).then(/* Callback function that sends response */)

別のオプションは、forループの代わりに再帰を使用して、停止条件に達したときにリクエストを送信することです。しかし、私は良い選択だとは思わない。なぜなら、collections配列が大きい場合、最大スタックサイズを超えることができるからです。

関連する問題