【问题标题】:I am using Async's Library Parallel method wrong? But how?我使用 Async 的 Library Parallel 方法错了吗?但是怎么做?
【发布时间】:2013-04-30 15:14:15
【问题描述】:

我正在使用async library's parallel 函数,但遇到了一个奇怪的问题。我遍历一个对象数组来创建一个称为人的函数数组。人们被传入异步的并行方法以并行执行。但是,当我查看实际传递给“printFunction”的参数“people”时,这是错误的。 people 参数始终是我的 people 数组中的最后一个对象。

所以在这个例子中,printFunction 中的控制台日志会打印出来

{ 'name' : 'jar jar binks' }
{ 'name' : 'jar jar binks' }

代码:

var people = [{ 'name' : 'obi wan kenobi'}, { 'name' : 'jar jar binks' }];

// Create an array of tasks to be processed.
for(var i = 0; i < people.length; i++) {
  tasks.push( function(callback) {
    setTimeout( makePrintFunction(people[i], callback), 200); 
  });
}

// Process those tasks.
async.parallel(tasks, function(err, stuff) {
  // ...do some stuff with the returned array here.
});

制作打印功能:

function makePrintFunction(people, next) {
  return validateAndTrackFlag(people, next);
}

function printFunction(people, next) {
  console.log(people);        // Always prints: { 'name' : 'jar jar binks' }
  next(null, true)
}

显然这不是真正的代码,我只是更改了名称和对象。

提前感谢您的帮助。

【问题讨论】:

标签: javascript node.js


【解决方案1】:

这不是异步问题,而是闭包问题。

试试这个:

for(var i = 0; i < people.length; i++) {
  (function (i){
    tasks.push( function(callback) {
      setTimeout( makePrintFunction(people[i], callback), 200); 
    });
  })(i)
}

或者这个:

people.forEach (function (p){
  tasks.push( function(callback) {
    setTimeout( makePrintFunction(p, callback), 200); 
  });
});

【讨论】:

    【解决方案2】:

    您正在处理经典的范围界定问题。试试这个:

    for(var i = 0; i < people.length; i++) {
      (function(i) {
        tasks.push( function(callback) {
          setTimeout( makePrintFunction(people[i], callback), 200); 
        });
      })(i);
    }
    

    甚至更好

    var create_scope = function(i) {
      tasks.push( function(callback) {
        setTimeout( makePrintFunction(people[i], callback), 200); 
      });
    };
    for (var i = 0; i < people.length; i++) {
      create_scope(i);
    }
    

    或最好的:

    people.forEach(function(person) {
      tasks.push( function(callback) {
        setTimeout( makePrintFunction(person, callback), 200); 
      });
    });
    

    发生这种情况是因为for 循环没有创建范围,即当函数被触发时,i 是最后一个索引。现在函数确实创建了作用域,所以匿名函数内部 i 是预期值。

    【讨论】:

    • people.forEach(function(person) { ... })
    • 天哪,你打败了我 :) (尽管forEach 回调的第一个参数将是数组项而不是索引 :)
    • 是的,太明显了,我不认为可能有错误。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-21
    • 2010-10-06
    • 1970-01-01
    • 1970-01-01
    • 2012-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多