2つの主な問題があります。
-
あなたの
phoneNumber
変数はあなたが望むものにはなりません。これは、.forEach()
に変更することで修正できます。 または.map()
配列の反復。これにより、現在の変数のローカル関数スコープが作成されます。 -
すべての非同期操作がいつ実行されたかを知る方法を作成しました。それを行う方法を示す重複した質問/回答がたくさんあります。おそらく
Promise.all()
を使用することをお勧めします 。
すでに持っている約束を活用するこのソリューションをお勧めします:
function getContactList(contacts) {
var contactList = {};
return Promise.all(contacts.filter(utils.isValidNumber).map(function(phoneNumber) {
return db.client().get(phoneNumber).then(function(reply) {
// build custom object
constactList[phoneNumber] = reply;
});
})).then(function() {
// make contactList be the resolve value
return contactList;
});
}
getContactList.then(function(contactList) {
// use the contactList here
}, funtion(err) {
// process errors here
});
これがどのように機能するかです:
-
contacts.filter(utils.isValidNumber)
を呼び出します 配列を有効な数値のみにフィルタリングします。 -
.map()
を呼び出します フィルタリングされた配列を反復処理する -
return db.client().get(phoneNumber)
.map()
から 約束の配列を作成するためのコールバック。 - 電話番号のデータを取得したら、そのデータをカスタムの
contactList
に追加します オブジェクト(これは本質的に.map()
の副作用です ループ。 -
Promise.all()
を使用します 返された一連のpromiseで、すべてがいつ完了したかを知ることができます。 -
contactList
を作成します 作成したオブジェクトは、返されたpromiseの解決値です。 - 次に、それを呼び出すには、返されたpromiseを
.then()
で使用します。 最終結果を得るには。ただ戻ることができるという約束がすでにある場合は、コールバック引数を追加する必要はありません。