【发布时间】:2014-12-04 01:24:22
【问题描述】:
使用 node.js 0.10 的 stream.Writable 基类,我该如何处理消费者调用 .end() 并因此发出信号不再可用的情况?
在the documentation 中,唯一被告知要在Writable 子类中实现的方法是_write,但我找不到任何干净的方法来通知输入何时用尽。
【问题讨论】:
使用 node.js 0.10 的 stream.Writable 基类,我该如何处理消费者调用 .end() 并因此发出信号不再可用的情况?
在the documentation 中,唯一被告知要在Writable 子类中实现的方法是_write,但我找不到任何干净的方法来通知输入何时用尽。
【问题讨论】:
我知道这已经过时了,但我在 2020 年遇到了这个问题。如果其他人在这里找到了方法:现在已在 Writable._final() 中实现,如文档中的 here 所述
【讨论】:
我找到的答案是监听finish 事件。
当
end()方法被调用,并且所有数据都被刷新到底层系统时,这个事件被触发。
我还没有测试它,但是我正在阅读这篇文章的方式,所有对_write 的调用必须在finish 事件发出之前完成。
【讨论】:
令人尴尬的是,从 0.10 开始,节点的 stream.Writable 不以标准、干净的方式支持这一点。这个问题已经在这里讨论过:https://github.com/joyent/node/issues/7348
在该页面中提出了几种解决方法。 TomFrost 的flushwritable 模块目前看起来是一个可以接受的解决方案。
该模块提供了一个FlushWritable 类,其使用方式与stream.Writable 完全相同,但支持一个新的_flush 方法,该方法在消费者调用.end() 之后但在finish 事件发出之前调用。
【讨论】:
来自 source code 的 nodejs 可写流。
如果流能够结束,调用end 将触发finish 事件。
如果您的流没有_final 函数,它也会触发prefinish 事件。
【讨论】:
考虑到你问的问题
如何处理消费者调用 .end() 并因此发出信号不再可用的情况?
,你应该检查你的输入(可读流)何时结束,而不是你的输出(你的可写流)。因此,在这种情况下,您可以检查可读流上的 end 事件,例如:
readableStream.on('end', function () {
// do what you want with your writable stream, maybe call the end() method
writableStream.end();
});
如果您不想自己管理流,您甚至可以将可读流通过管道传输到可写流:
readableStream.pipe(writableStream);
【讨论】:
.pipe() 或直接使用.write()。在某个时间点,输入将被完全刷新,我的流将收到.end() 调用(直接或作为.pipe() 行为的一部分)。我希望我的可写流能够检测到这一点,例如关闭它正在写入的文件。