【问题标题】:Event listener when the transformation of the stream is finished, Node.js流转换完成时的事件监听器,Node.js
【发布时间】:2015-07-27 02:48:31
【问题描述】:

我正在尝试在管道转换中的数据末尾注册事件侦听器。我曾是 尝试将事件注册到管道中的所有流:

a) 我的自定义转换流 (StreamToBuffer)
b) 标准文件读取流
c) 标准 gunzip 流。

但不幸的是,它们都不起作用(参见下面的代码)。据我所知 试试看,只有 'data' 事件有效,但无济于事。

我需要的是在StreamToBuffer转换完成后继续处理tailBuffer

您能建议如何实现这一目标吗?

代码(为简洁起见):

function samplePipe() {
    var streamToBuffer = new StreamToBuffer();
    var readStream = fs.createReadStream(bgzFile1, { flags: 'r',
        encoding: null,
        fd: null,
        mode: '0666',
        autoClose: true
    });
    var gunzipTransform = zlib.createGunzip();
    readStream.on('end', function() {
        //not fired
        console.log('end event readStream');
    });
    streamToBuffer.on('end', function() {
        //not fired
        console.log('end event streamBuffer');
    });
    gunzipTransform.on('end', function() {
        //not fired
        console.log('end event gunzipTransform');
    });
    readStream
        .pipe(gunzipTransform)
        .pipe(streamToBuffer)
    ;
}

StreamToBuffer:

function StreamToBuffer() {
    stream.Transform.call(this);
    this.tailBuffer = new Buffer(0);
}

util.inherits(StreamToBuffer, stream.Transform);

StreamToBuffer.prototype._transform = function(chunk, encoding, callback) {
    this.tailBuffer = Buffer.concat([this.tailBuffer, chunk]); 
    console.log('streamToBuffer');
}

StreamToBuffer.prototype._flush = function(callback) {
    callback();
}

module.exports = StreamToBuffer;

已编辑: 在将回调函数传递给 StreamToBuffer 构造函数后,我发现了错误 - _transform() 方法中缺少 callback();。添加后,事件“结束”侦听器可以工作,至少在标准读取流上。

StreamToBuffer.prototype._transform = function(chunk, encoding, callback) {
    this.tailBuffer = Buffer.concat([this.tailBuffer, chunk]); 
    console.log('streamToBuffer');
    callback();
}

另一种方法是将回调函数传递给StreamToBuffer构造函数,然后在_flush方法中调用它。这样做的好处是我们可以确定转换完成。

function samplePipe() {
    var streamToBuffer = new StreamToBuffer(processBuffer);
.....
}

function processBuffer(buffer) {
    console.log('processBuffer');
}

StreamToBuffer:

function StreamToBuffer(callback) {
    stream.Transform.call(this);
    this.tailBuffer = new Buffer(0);
    this.finishCallback = callback;
}

util.inherits(StreamToBuffer, stream.Transform);

StreamToBuffer.prototype._transform = function(chunk, encoding, callback) {
    this.tailBuffer = Buffer.concat([this.tailBuffer, chunk]); 
    console.log('streamToBuffer');
    callback();
}

StreamToBuffer.prototype._flush = function(callback) {
    console.log('flushed');
    callback();
    this.finishCallback(this.tailBuffer);
}

module.exports = StreamToBuffer;

虽然我还没有收到任何答案(无论如何感谢其他 cmets),但我认为这个问题对于像我这样正在学习 node.js 的人很有用。如果您知道更好的解决方案,请回答。谢谢。

【问题讨论】:

  • 我认为最好的方法是使用promise:github.com/kriskowal/q
  • 在这些情况下,您通常可以在下面回答自己的问题,而不是自己回答问题。

标签: node.js


【解决方案1】:

对于可写流,尝试finish 事件而不是end 事件:

streamToBuffer.on('finish', function() {
  // finish event fired
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-24
    • 2022-10-15
    • 2020-10-13
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-23
    相关资源
    最近更新 更多