在循环内异步更改对象,然后返回修改后的对象

时间:2016-09-23 11:12:58

标签: loops promise bluebird

问题是"然后"在" 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);
});

甚至可以这样做吗?

1 个答案:

答案 0 :(得分:0)

这可能适合你。几乎所发生的事情getUsernameById正在返回一个承诺,我们在其上调用then这一事实就证明了这一点,并且then本身会返回一个承诺。因此,我们所做的就是每次选择相关的每次投票,我们都会向我们的promises数组提出承诺。在获得用户名并修改了正确的投票和选择后,这些承诺中的每一个都得到解决。

然后你可以在promises数组上使用all,它返回一个在promises数组中的所有promise都已解析后解析的promise。你的上一个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);
});

希望这会有所帮助。如果您有任何问题,请告诉我。