Du har två huvudfrågor.
-
Ditt
phoneNumber
variabeln blir inte vad du vill att den ska vara. Det kan fixas genom att ändra till en.forEach()
eller.map()
iteration av din array eftersom det kommer att skapa ett lokalt funktionsomfång för den aktuella variabeln. -
Du har skapat ett sätt att veta när alla asynkroniseringsoperationer är gjorda. Det finns massor av dubbletter av frågor/svar som visar hur man gör det. Du vill förmodligen använda
Promise.all()
.
Jag skulle föreslå den här lösningen som utnyttjar de löften du redan har:
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
});
Så här fungerar det:
- Ring
contacts.filter(utils.isValidNumber)
för att filtrera arrayen till endast giltiga nummer. - Ring
.map()
att iterera genom den filtrerade arrayen return db.client().get(phoneNumber)
från.map()
återuppringning för att skapa en rad löften.- När du har fått uppgifterna för telefonnumret lägger du till dessa uppgifter i din anpassade
contactList
objekt (detta är i huvudsak en bieffekt av.map()
loop. - Använd
Promise.all()
på den returnerade mängden löften att veta när alla är klara. - Skapa
contactList
objektet som vi byggt upp vara värdet av det returnerade löftet. - För att kalla det, använd bara det returnerade löftet med
.then()
för att få det slutliga resultatet. Du behöver inte lägga till ett återuppringningsargument när du redan har ett löfte om att du bara kan återvända.