NodeJS:将异步树遍历转换为可读流

时间:2014-09-23 20:49:39

标签: node.js asynchronous recursion stream

受到关于这个问题的最高评价答案的启发:node.js fs.readdir recursive directory search,我一直试图将答案重构为可读流。到目前为止没有运气。

似乎它正在进行无休止的递归。

var stream = require('stream');
var Readable = stream.Readable;
var util = require('util');

util.inherits(Images, Readable);

function Images(images_dir, opt) {
    Readable.call(this, opt);
    this.images_dir= images_dir;
    this.pending = 1;
}

Images.prototype._read = function() {
    var that = this;
    this.walk(this.images_dir, function(err, file) {
        if(err) {throw err;}
        that.pending--;
        if(that.pending == 0) {
            console.log('done');
            //that.push(null);
        }
    });
};

Images.prototype.walk = function(dir, done) {
    var that = this;
    console.log('pending: ' + that.pending + ', scanning dir ' + dir);
    fs.readdir(dir, function(err, list) {
        if (err) return done(err);
        that.pending +=  list.length;
        list.forEach(function(file_or_dir, index) {
            file_or_dir = dir + '/' + file_or_dir;
            fs.stat(file_or_dir, function(err, stat) {
                if (err) return done(err);
                if (stat && stat.isDirectory()) {
                    that.walk(file_or_dir, done);
                } else {
                    //that.push(file_or_dir);
                    console.log('pending: ' + that.pending + ', sending file ' + file_or_dir);
                    return done(null);
                }
            });
            if(index == (list.length - 1)) {
                return done(null);
            }
        });
    });
};


var images = new Images(images_dir);
images.pipe(process.stdout);

更新:我已更新代码以显示它与控制台日志一起使用,但是当我使用push函数时它不会。只需取消注释推送功能,它就会永远运行。

解决方案:我已将对this.walk的递归调用移至Images构造函数。这意味着文件路径在流中缓冲,直到消费者连接为止。定义_read函数(https://github.com/substack/stream-handbook#creating-a-readable-stream)仍然会更好。但就是这样。

0 个答案:

没有答案