【问题标题】:Node.js async directory traversal with accumulator带累加器的 Node.js 异步目录遍历
【发布时间】:2014-10-30 17:57:59
【问题描述】:

我想使用 node 获取包含在包含子目录的目录中的唯一文件名列表,并且在组合每个回调的结果时遇到了一些麻烦。我想避免重复操作,如果我只是从fs.stat 回调中记录文件名,就会发生这种情况。

var distinct = {};

function getNames(root) {
    fs.readdir(root, function(err, list) {
        list.forEach(function(file) {
            file = root + '/' + file; 
            fs.stat(file, function(err, stat) {
                if (!err && stat.isDirectory()) {
                    getNames(file);
                } else {
                    distinct[path.basename(file)] = true;
                }
            });
        });
    });
}

// perform various operations on unique filename list
console.log(Object.keys(distinct));

当然,这会过早调用console.log() 函数并产生不希望的结果。我怎样才能获得一组文件名来处理;有没有使用异步方法的好方法,即不必使用readdirSyncstatSync

【问题讨论】:

  • 一个提示,使用path.join(root, file) 而不是root + '/' + file

标签: node.js asynchronous recursion accumulator


【解决方案1】:

异步模块将成为您的朋友。

var distinct = {};
function getNames(root, callback) {
    fs.readdir(root, function(err, list) {
        if (err) return callback(err);   

        async.each(list, function(file, done) {
            fs.stat(file, function(stat) {
                if (err) return done(err);
                if (stat.isDirectory()) return getNames(file, done);
                distinct[path.basename(file)] = true;
                done();
            });
        }, function(err) {
            // called when all done or error
            callback(err, distinct);
        })
    });
}

那么你就可以像这样使用它了

getNames('path/to/dir', function(distinct) {
    // logic
});

【讨论】:

    【解决方案2】:

    我可以建议使用promises吗?

    function getNames(root) {
        readdir = Q.nfbind(fs.readdir);
        stat = Q.nfbind(fs.stat);
        return readdir(root)
            .then(function(list) {
                files = [];
                for(var i = 0; i < list.length; i++) {
                    file = root + '/' + list[i]; 
                    files.push(stat(file)
                        .then(function(stat) {
                            if (stat.isDirectory()) {
                                return getNames(file);
                            } else {
                                return path.basename(file);
                            }
                         })
                    );
                }
                return Q.all(files);
            });
    }
    getNames('someDir')
        .then(console.log)
        .catch(console.error);
    

    【讨论】:

      猜你喜欢
      • 2016-10-26
      • 2011-10-25
      • 2019-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-24
      相关资源
      最近更新 更多