我正在尝试使用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]是未定义的。为什么会这样?我觉得有一些奇怪的任务和范围正在进行......
如果问题(和代码)没有立即明显,我对编程很陌生......
答案 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循环已经完成,因此src
和dest
将为每个调用设置最终循环值到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
作为错误,因为这是您在示例中所做的事情,但您可能不应该丢弃错误,因为它们可能很重要。