Имате два основни проблема.
-
Вашият
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()
върху върнатия масив от обещания, за да разберете кога са готови. - Направете
contactList
обектът, който изградихме, да бъде стойността на разрешаване на върнатото обещание. - След това, за да го извикате, просто използвайте върнатото обещание с
.then()
за да получите крайния резултат. Няма нужда да добавяте аргумент за обратно извикване, когато вече имате обещание, което можете просто да върнете.