我正在尝试使用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中的函数数,results数组回调包含数组中最后一个并行任务的结果,n次。我想不通。似乎每个函数都应该用(null,url)向并行函数返回自己的回调。
此外,当我尝试使用src和dest的定义直接调用self.pload函数时:
self.upload(fileArr[i]['path'], fileArr[i]['dest'], headers, function(err, url) {
cb(null, url)
})
我收到一个错误,说"无法读取未定义的属性'path'"。因此,fileArr[i]是未定义的。为什么会发生这种情况?我觉得任务和范围有点奇怪…
如果从问题(和代码)中看不出来,我对编程还很陌生。。
请记住,这本质上是:
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'], ...
,在函数运行时,由于for循环已经完成,因此i === fileArr.length
的值也会出现。
对此,最简单的解决方案是使用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
作为错误传递,因为这就是您在示例中所做的,但您可能不应该丢弃错误,因为它们可能很重要。