node.js async parallel函数多次返回单个结果

时间:2013-11-20 00:44:30

标签: node.js asynchronous

我正在尝试使用node.js的异步模块并行上传多个文件。我的代码如下:

// fileArr is an array of objects. each object contains the attributes of the file to be uploaded - filename, path, destination path, etc.

// toUpload is an array to which i push all the functions i want to execute with async.parallel

  for (i=0; i<fileArr.length; i++) {
    var src = fileArr[i]['path']
    var dest = fileArr[i]['dest']
    var fn = function(cb) { self.upload(src, dest, headers, function(err, url) { 
      cb(null, url)   
    })  
  }
  toUpload.push(fn) 
  } // for loop ends here

async.parallel(toUpload, function(err, results) {
  console.log('results: ' + results)
}) 

我的问题:对于n = toUpload中的函数个数,结果数组回调包含数组中最后一个并行任务的结果n次。我无法弄清楚这一点。似乎每个函数都应该将自己的回调函数(null,url)返回到并行函数。

也 - 当我尝试直接调用带有src和dest定义的self.upload函数时:

self.upload(fileArr[i]['path'], fileArr[i]['dest'], headers, function(err, url) {
  cb(null, url)
})

我收到一条错误,说“无法读取未定义的属性'路径'”。所以,fileArr [i]是未定义的。为什么会这样?我觉得有一些奇怪的任务和范围正在进行......

如果问题(和代码)没有立即明显,我对编程很陌生......

1 个答案:

答案 0 :(得分:1)

请记住,这基本上是:

var src, dest
for (i=0; i<fileArr.length; i++) {
  src = fileArr[i]['path']
  dest = fileArr[i]['dest']
  var fn = function(cb) {
    self.upload(src, dest, headers, function(err, url) { 
      cb(null, url)   
  })  
}

可能会更清楚地表明,当调用fn函数时,for循环已经完成,因此srcdest将为每个调用设置最终循环值到fn

同样,对于self.upload(fileArr[i]['path'], fileArr[i]['dest'], ...,在函数运行时,i === fileArr.length的值因为for循环已经完成。

最简单的解决方案是使用async.map代替。

async.map(
  fileArr,
  function(file, callback){
    self.upload(file['src'], file['dest'], headers, function(err, url){
      callback(null, url);
    });
  },
  function(err, results) {
    console.log('results: ' + results)
  }
)

我正在传递null作为错误,因为这是您在示例中所做的事情,但您可能不应该丢弃错误,因为它们可能很重要。