Node Js异步回调和递归

时间:2014-04-09 00:45:05

标签: node.js recursion path directory fs

我想做这样的事情

function scan(apath){
    var files = fs.readdirSync(apath);
    for(var i=0; i<files.length;i++){
        var stats = fs.statSync(path.join(apath,files[i]))
        if(stats.isDirectory()){
            results.push(path.join(apath, files[i]))
            scan(path.join(apath,files[i]))
        }
        if(stats.isFile()){
            results.push(path.join(apath,files[i]))
        }
    }
}

但异步。

尝试使用异步函数让我陷入了类似这样的噩梦。

function scan(apath){
    fs.readdir(apath, function(err, files)){
        var counter = files.length;
        files.forEach(function(file){
            var newpath = path.join(apath, file)
            fs.stat(newpath, function(err, stat){
                if(err) return callback(err)
                if(stat.isFile())
                    results.push(newpath)
                if(stat.isDirectory()){
                    results.push(newpath)
                    scan(newpath)
                }
                if(--counter <=0) return

            })
        })
    }
}

所有地狱在节点堆栈中都会崩溃,因为事情不会像在同步方法中那样在逻辑上连续发生。

1 个答案:

答案 0 :(得分:0)

您可以尝试使用异步模块,并使用如下:

function scan(apath, callback) {
    fs.readdir(apath, function(err, files) {
        var counter = 0;
        async.whilst(
            function() {
                return counter < files.length;
            },
            function(cb) {
                var file = files[counter++];
                var newpath = path.join(apath, file);
                fs.stat(newpath, function(err, stat) {
                    if (err) return cb(err);
                    if (stat.isFile()) {
                        results.push(newpath);
                        cb(); // asynchronously call the loop
                    }
                    if (stat.isDirectory()) {
                        results.push(newpath);
                        scan(newpath, cb); // recursion loop
                    }
                });
            },
            function(err) {
                callback(err); // loop over, come out
            }
        );
    });
}

了解有关async.whilst

的更多信息