繁体   English   中英

向回调函数添加其他参数

[英]Add additional parameters to callback function

我正在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()获取错误的路径。 发生这种情况是因为在回调运行时,下一个循环已经开始 - 意味着路径变量已经改变。

所以,我需要做的是以某种方式将路径变量锁定到它的特定回调函数。 我想不出有什么好办法 - 任何人都有一些想法?

没有块范围,因此请使用范围函数。

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);
    }
}

对我来说这是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);
    );
}

无论哪种方式,重要的一点是函数的上下文(匿名或非匿名)是在重新分配路径变量的值之前启动的。

这实际上是JavaScript的一个恼人的功能,以至于CoffeeScript的(这是编译为Java脚本语言),有一个处理它的特定方式, 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)

我一直在寻找相同的东西并最终得到解决方案,这里有一个简单的例子,如果有人想要通过这个。

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')

来自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也会被重置,并且在执行回调时你会发现它是'undefined'。 试试这个简单的例子:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM