2016-09-23 57 views
0

問題是,「then」在「getUsernameById」完成了循環中的作業之前觸發。在循環內異步更改對象,然後返回修改的對象

var dummyObject = { 
    choices: [ 
     { 
      votes: [ 
       "1234", 
       "2143", 
       "4321" 
      ] 
     } 
    ] 
}; 

Promise.each(dummyObject.choices, function(choice, i) { 
    dummyObject.choices[i].test = "test"; // this gets changed before 'then' 
    Promise.each(choice.votes, function(vote, j) { 
     getUsernameById(vote).then(function(username) { 
      dummyObject.choices[i].votes[j] = username; // this gets changed after 'then' 
     }); 
    }); 
}).then(function() { 
    res.json(dummyObject); 
}); 

甚至可以這樣做嗎?

+0

如果您使用一些提供'Promise.each'的promises庫,請用您的問題名稱來標記您的問題。順便說一句,你確定你不錯過這裏或那裏的「回報」嗎? – 2016-09-23 11:35:40

回答

0

這可能適合你。幾乎所發生的事情是getUsernameById正在返回一個承諾,證明了我們打電話給then的事實,並且then本身返回一個承諾。因此,我們正在爲每個選擇與每個投票相關聯,我們正在向我們的promises陣列投入承諾。在獲得用戶名並修改了正確的選票和選項後,這些承諾中的每一個都會得到解決。

然後,您可以在promises數組上使用all,該數組返回承諾,在promises陣列中的所有承諾都已解決後解決。您的最後一個then只會在所有這些發生後纔會觸發,此時,您的dummyObject應該正確更新。

var dummyObject = { 
    choices: [ 
     { 
      votes: [ 
       "1234", 
       "2143", 
       "4321" 
      ] 
     } 
    ] 
}; 

var promises = []; 

dummyObject.choices.forEach(function (choice, i) { 
    choice.votes.forEach(function (vote, j) { 
    var userPromise = getUsernameById(vote).then(function (username) { 
     dummyObject.choices[i].votes[j] = username; 
    }); 

    promises.push(userPromise);   
    }); 
}); 

return Promises.all(promises).then(function() { 
    res.json(dummyObject); 
}); 

希望這會有所幫助。如果您有任何疑問,請告訴我。