2017-06-15 5 views
0

私はこのようなnodejs Mongodbコードを持っています。私はグローバル配列にプッシュしようとしているすべての結果を返しますが、配列は1つだけの値が含まれています。どんな考え?配列.pushがpromise関数内で動作していません

var s = []; 
var p = function(){ 
return new Promise(function(resolve, reject) { 
    MongoClient.connect(url, function (err, db) { 

    db.listCollections().forEach(function(collname) { 

    db.collection(collname.name).find().sort({ duration_in_seconds: 1 }).limit(1).toArray(

    function(err, docs) { 

     assert.equal(null, err); 
     s.push(docs); 
     resolve(); 
     }); 


}); 

}); 

}); 

} 


p().then(function() { 

    console.log(s); 

}); 
+0

あなたがの範囲外の変数を参照することはできませんがこれらのヘルパーを使用してpは、すべての結果の配列のための約束権を得Promise.all、それらをアレイ内の各コレクションのための約束を入れて、そして待ちますそのような約束。代わりに "内側"で作業してください。 [複製を読んで理解する](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) –

+0

どうすればいいですか?私は@NeilLunnを約束するために新しいです – karthik006

+0

@NeilLunnここでの問題は約束ではなく、それは 'forEach'ループです – Bergi

答えて

2

最初のコレクションがドキュメントを返すときに約束を解決しています。それらのすべてを待つ必要があります。代わりに、独自に大きなnew Promisepromisifyすべての非同期機能のすべてを包み、そして返された約束ではなく、グローバル変数に入れるので結果値をを満たす作るの:

function connect(url) { 
    return new Promise(function(resolve, reject) { 
     MongoClient.connect(url, function (err, db) { 
      if (err) reject(err); 
      else resolve(db); 
     }); 
    }); 
} 
function getArray(cursor) { 
    return new Promise(function(resolve, reject) { 
     cursor.toArray(function(err, docs) { 
      if (err) reject(err); 
      else resolve(docs); 
     }); 
    }); 
} 

は今、あなたが書くことができます

function p() { 
    return connect(url).then(function(db) { 
     return getArray(db.listCollections()).then(function(collections) { 
      var promises = collections.map(function(collname) { 
       return getArray(db.collection(collname.name).find().sort({duration_in_seconds: 1 }).limit(1)); 
      }); 
      return Promise.all(promises); 
     }); 
    }); 
} 

p().then(function(s) { 
    console.log(s); 
}); 
+0

ありがとうございました。私は試しましたが、このエラーが発生しました。 "TypeError:db.listCollections(...)。mapは関数ではありません" – karthik006

+0

ああ、私は 'listCollections'が配列を返すことを期待していました(標準' forEach'と 'map'メソッド)であり、待たなければならない非同期カーソルではありません。しかし、それにも合わせることができます。 – Bergi

+0

ああ、私が思ったことはそうです。ありがとうございましたBergi – karthik006

関連する問題