我有一些代码可以为 dirs
数组中的每个源目录和目标目录复制数组中包含的文件。通过循环的每次迭代,它都会调用复制的函数。它看起来像这样:
var filesInEachDir ["file1", "file2", "file3"];
var dirs = [
{"source": "sourceDirectory1", "dest":"destinationDirectory1"},
{"source": "sourceDirectory2", "dest":"destinationDirectory2"},
{"source": "sourceDirectory3" "dest":"destinationDirectory3"},
];
for (var i = 0; i < dirs.length; i++){
fs.mkdir(dirs[i], function(err){
if(err){
console.log(err);
}else{
copyFiles(dirs[i], filesInEachDir);
}
});
}
function copyFiles(dirs, files){
for (var c = 0; c < files.length; c++){
fs.copy(files[c], dirs.source, dirs.dest, {replace: false}, function(err){
if (err){
console.log(err);
}else{
console.log('file copied');
}
});
}
}
由于某些原因,只有 dirs
的最后一个元素中的文件被复制。如果我将另一个元素添加到 dirs
,它的文件将被复制,而不是任何其他元素。所以看起来 i
在调用 copyFiles
函数之前完全递增。为什么会这样?如何为 copyFiles
提供 i
的每个增量值?
最佳答案
您遇到了在异步函数上使用 for
循环引起的经典问题:循环在它调用的任何函数完成之前很久就结束了,所以当第一个函数真正开始做某事时,它引用的循环索引已被覆盖。
改用 .forEach
以避免覆盖循环索引。
var filesInEachDir = ["file1", "file2", "file3"];
var dirs = [
{"source": "sourceDirectory1", "dest":"destinationDirectory1"},
{"source": "sourceDirectory2", "dest":"destinationDirectory2"},
{"source": "sourceDirectory3", "dest":"destinationDirectory3"}
];
dirs.forEach(function (dir) {
fs.mkdir(dir, function(err) {
if (err) {
console.log(err);
} else {
copyFiles(dir, filesInEachDir);
}
});
});
function copyFiles(dir, files) {
files.forEach(function (file) {
fs.copy(file, dir.source, dir.dest, {replace: false}, function(err) {
if (err) {
console.log(err);
} else {
console.log('file copied');
}
});
});
}
它归结为正确地确定变量的范围。在您的代码中,从 mkdir
回调中查看时, i
处于更高范围。 i
的内容由 for
循环从外部控制。您需要一个本地 数组索引。
您可以使用 IIFE关闭 i
并创建一个回调,它有自己的副本:
for (var i = 0; i < dirs.length; i++){
fs.mkdir(dir, (function (i) {
return function(err) {
if (err) {
console.log(err);
} else {
copyFiles(dirs[i], filesInEachDir);
}
};
})(i));
}
或者更好
for (var i = 0; i < dirs.length; i++){
fs.mkdir(dir, (function (dir) {
return function(err) {
if (err) {
console.log(err);
} else {
copyFiles(dir, filesInEachDir);
}
};
})(dirs[i]));
}
...这在技术上等同于使用 .forEach
,只是看起来不那么容易。
关于javascript - For循环在传递给函数之前递增到限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31575009/