我正在Node.js中构建一个系统,它应该找到文件夹数组中的所有文件,对它们进行统计,然后使用该信息做一些额外的工作。
我正在使用fs.readdir()从每个文件夹中同步获取所有文件。我的代码如下所示:
for(i=0,max=paths.length; i<max; i++) {
var path = paths.pop();
console.log("READING PATH: " + path);
fs.readdir(path, function(err, files) { handleDir(err, files, path); });
}
问题是,根据readdir()执行的速度,handleDir()获取错误的路径。这是因为在回调运行时,下一个循环已经开始 - 意味着路径变量已经改变。
所以,我需要做的是以某种方式将路径变量锁定到它的特定回调函数。我想不出有什么好办法 - 任何人都有一些想法吗?
答案 0 :(得分:8)
没有块范围,因此请使用范围函数。
for(var i=0, path, max=paths.length; i<max; i++) {
path = paths.pop();
console.log("READING PATH: " + path);
handlePath( path );
}
function handlePath ( path ) {
fs.readdir(path, onPathRead);
function onPathRead (err, files) {
handleDir(err, files, path);
}
}
答案 1 :(得分:6)
对我来说,这是JS中比较烦人的部分之一。创建单独函数(如@generalhenry演示)的另一种方法是将代码包装在路径变量更改之前执行的匿名函数中。
for(i=0,max=paths.length; i<max; i++) {
var path = paths.pop();
console.log("READING PATH: " + path);
fs.readdir(path,
(function(p){
return function(err, files) {
handleDir(err, files, p);
};
})(path);
);
}
无论哪种方式,重要的一点是函数的上下文(匿名或非匿名)是在重新分配路径变量的值之前启动的。
答案 2 :(得分:1)
这确实是Javascript的烦人功能,以至于Coffeescript(这是一种编译为Javascript的语言)有一种特定的处理方式,do
运算符for
。在Coffeescript中,您的原始功能将是:
for path in paths
fs.readdir path, (err, files) -> handleDir(err, files, path)
问题的解决方案是:
for path in paths
do (path) ->
fs.readdir path, (err, files) -> handleDir(err, files, path)
答案 3 :(得分:0)
我一直在寻找相同的东西并最终得到了解决方案,如果有人想要解决这个问题,这是一个简单的例子。
var FA = function(data){
console.log("IN A:"+data)
FC(data,"LastName");
};
var FC = function(data,d2){
console.log("IN C:"+data,d2)
};
var FB = function(data){
console.log("IN B:"+data);
FA(data)
};
FB('FirstName')
答案 4 :(得分:0)
Generalhenry的出色解决方案,但是如果要在回调函数中使用try / catch结构,请小心
function handlePath ( path ) {
fs.readdir(path, onPathRead);
function onPathRead (err, files) {
try {
handleDir(err, files, path);
} catch (error) {
var path = 'something_else'; // <<--- Never do this !!!
}
}
}
请不要尝试在catch块中重新声明相同的var,即使从未调用过catch块,也会重置路径var,并且在执行回调时您会发现它为“未定义”。 试试这个简单的例子:
function wrapper(id) {
console.log('wrapper id:' + id);
setTimeout(callback, 1000);
function callback() {
try {
console.log('callback id:' + id);
} catch (error) {
var id = 'something_else';
console.log('err:' + error);
}
}
}
wrapper(42);
这将输出:
wrapper id:42
callback id:undefined