【发布时间】: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