node.js中的for循环和异步回调?

时间:2011-09-01 09:41:37

标签: node.js asynccallback

我是JavaScript和node.js的新手。我想遍历一个目录并将所有文件stat(不是其他目录)添加到数组中。如下所示,我的代码存在问题,因为在for循环结束后可能会调用回调,因此在回调方法中使用“i”变量将无效。但是代码应该如何看待下面的代码片段呢?它与闭合有关吗?

感谢您的帮助!

    fs.readdir(SYNCDIR, function(err1, files) {
        var filesOnly = [];

        if(!err1) {

            for(var i = 0; i < files.length; i++) {

                var imgFilePath = SYNCDIR + '/' + files[i];
                fs.stat(imgFilePath, function(stat){

                    if (stat.isFile()){
                        filesOnly[i] = stat; // This will not be correct since the for-loop has finished
                    }
                });

            }
        }
    });

3 个答案:

答案 0 :(得分:32)

你是否需要使用闭包。您应该在自调用函数中包装for循环的内容,以便为每次迭代保留i的值。

fs.readdir(SYNCDIR, function(err1, files) {
    var filesOnly = [];

    if(!err1) {

        for(var i = 0; i < files.length; i++) {

            (function(i) {
                var imgFilePath = SYNCDIR + '/' + files[i];
                fs.stat(imgFilePath, function(stat){
                    if (stat.isFile()){
                        filesOnly[i] = stat;
                    }
                });
            })(i);

        }
    }
});

答案 1 :(得分:10)

一种方法是重写循环的内部以使用闭包:

fs.readdir(SYNCDIR, function(err1, files) {
    var filesOnly = [];
    if(!err1) {
        for(var i = 0; i < files.length; i++) {
            (function(index) {
                var imgFilePath = SYNCDIR + '/' + files[index];
                fs.stat(imgFilePath, function(stat){
                    if (stat.isFile()){
                        filesOnly[index] = stat;
                    }
                });
            })(i);
        }
    }
});

一个更好看的示例,使用Array.prototype.forEach实现相同的效果:

fs.readdir(SYNCDIR, function(err1, files) {
    var filesOnly = [];
    if(!err1) {
        files.forEach(function(file, i) {
            var imgFilePath = SYNCDIR + '/' + file;
            fs.stat(imgFilePath, function(stat){
                if (stat.isFile()){
                    filesOnly[i] = stat;
                }
            });
        });
    }
});

答案 2 :(得分:0)

或者使用新的线程模块(https://github.com/robtweed/Q-Oper8)然后你可以更简单地使用线程子进程中的标准同步编码来完成所有这些工作,因为它们一次只处理一个用户的请求。 / p>

再见异步逻辑和嵌套回调!

相关问题