Promise.all()解析为每个promise

时间:2017-09-16 21:40:04

标签: javascript node.js promise es6-promise

我正在编写一个模块,该模块具有使用Promise.all()向多个用户发送电子邮件来返回承诺的功能。删除代码,我能够将问题重现到以下代码段:

var getPromise = function(data) {
    return new Promise((resolve, reject) => {
        console.log("After Calling:\t\t", data.user);
        setTimeout(function() {
                console.log("While Resolving:\t", data.user);
                return resolve(data);
            },
            Math.random() * 1000);
    });
}

var getAllPromises = function(users, options) {
    var promises = [];
    users.forEach(user => {
        var userSpecificOptions = options;
        // var userSpecificOptions = {};
        userSpecificOptions.user = user;
        promises.push(getPromise(userSpecificOptions));
    });
    return Promise.all(promises);
}

var userlist = ["help", "promises", "are", "tough"];
var commonoptions = {
    str: "something",
}

getAllPromises(userlist, commonoptions)
    .then(data => console.log("Data:\n", data))

这给了我以下输出:

After Calling:       help
After Calling:       promises
After Calling:       are
After Calling:       tough
While Resolving:     tough
While Resolving:     tough
While Resolving:     tough
While Resolving:     tough
Data:
 [ { str: 'something', user: 'tough' },
  { str: 'something', user: 'tough' },
  { str: 'something', user: 'tough' },
  { str: 'something', user: 'tough' } ]

但是,切换userSpecificOptions的声明:

        // var userSpecificOptions = options;
        var userSpecificOptions = {};

获得正确的结果:

After Calling:       help
After Calling:       promises
After Calling:       are
After Calling:       tough
While Resolving:     help
While Resolving:     promises
While Resolving:     are
While Resolving:     tough
Data:
 [ { user: 'help' },
  { user: 'promises' },
  { user: 'are' },
  { user: 'tough' } ]

可能是什么问题?我觉得可能会有一些关于Promise如何工作的遗漏。

2 个答案:

答案 0 :(得分:1)

您使所有userSpecificOptions个实例引用相同的options对象:

var userSpecificOptions = options;

因此,当您分配到userSpecificOptions.user时,实际上会修改options

相反,您应该复制options

var userSpecificOptions = Object.assign({}, options);

然后对该特定userSpecificOptions对象的任何更改都不会影响options或任何其他变量。

答案 1 :(得分:0)

这个问题不在承诺中。在Javascript对象中通过引用传递。这意味着在这种情况下,您始终更改同一个对象,并且最后一次更改发生,您会看到所有相同的结果。它在创建新对象时起作用,而不是修改存在对象。