0

在进行 nodejs 编程时,我发现了一个简单但有趣的问题。
为了轮流执行一组异步函数,我通常将“作业列表数组”与 async.series 一起使用。

通过以下步骤:

1. 定义一个数组
2. 将作业函数推入数组。
3. 使用 async.series,按顺序执行。
例如 async.series(jobFunctionList, callback);

以下示例代码是简化的。
在评论中描述,它不像我预期的那样工作。即使在定义了 Job 函数并将其推入 jobList 数组后

,变量 'key' 和 'value' 也会发生变化。 似乎 push 函数不断引用外部变量,而不是创建环境的值。





我找到了解决此问题的解决方案,但不知道为什么会这样。

var dataList = { key1: 'value1', key2: 'value2' };

var jobList = new Array();

for (var key in dataList)
{
    var value = dataList[key];

    jobList.push(
        function (next)
        {
            console.log(key + ' : ' + value);
        }
    );
}

(jobList[0])();
(jobList[1])();

/* Expected Output :

key1 : value1
key2 : value2

*/

/* Real Output :

key2 : value2  <--- WHY ???
key2 : value2

*/
4

2 回答 2

2

正如 Teemu 所说,这是因为当 for 循环完成时,值已经改变了

您需要执行以下操作:

var dataList = { key1: 'value1', key2: 'value2' };

var jobList = new Array();

for (var key in dataList)
{
    var value = dataList[key];

    jobList.push(
        (function(savedKey, savedValue) {
            return function (next) {
                console.log(savedKey + ' : ' + savedValue);
            }
        })(key, value)
    );
}

(jobList[0])();
(jobList[1])();

虽然savedKeyandsavedValue可以被称为keyandvalue并且它会引用新的,这可能更有意义阅读它

于 2013-10-24T14:40:24.623 回答
2

匿名函数使用(共享)外部范围的相同键和值变量。当 for 结束时,他们使用的值是 key2 value2,而不是他们在定义函数时拥有的值。

for (var key in dataList) // definition of key
{
    var value = dataList[key]; // definition of value

    jobList.push(
        function (next)
        {
            console.log(key + ' : ' + value); // uses key and value from the outer scope
        }
    );
}

(jobList[0])(); // key and value are key2 value2 after for, so they are printed
(jobList[1])(); // same

解决方案是创建一个闭包,其中键和值是本地的:

for (var key in dataList) // definition of key
{
    var value = dataList[key]; // definition of value

    jobList.push(
      function(k,v){ // k,v local copies of key and value
        return function (next)
          {
            console.log(k + ' : ' + v); // uses local copies, created one for each iteration
          }
      }(key,value); // immediately execute the outer anonymous function, it just creates a local scope
    );
}
于 2013-10-24T14:44:00.430 回答