Node.js 可写流:write vs _write
Posted
技术标签:
【中文标题】Node.js 可写流:write vs _write【英文标题】:Node.js Writable stream: write vs _write 【发布时间】:2020-08-08 08:06:48 【问题描述】:我正在阅读 Node.js 官方文档以了解流。我正在实现可写流,但我不明白write
和_write
之间的区别。
引用this 部分的文档:
在这段时间之间发生的所有对 writable.write() 的调用 writable._write() 被调用并且回调被调用将导致 写入要缓冲的数据。当回调被调用时,流 可能会发出“排水”事件。如果流实现能够 一次处理多个数据块,writable._writev() 方法应该被实现。
这只是让我觉得两者的行为不同,但我不明白如何。
可能是通过在文档中以here 为基础的示例,任何人都可以解释下面给出的代码 sn-ps 在从Readable/Transform
流接收数据时的行为方式有何不同? Readable
流中的 write
和 _write
对应项(如果有)是什么?
const Writable = require('stream');
const myWritable = new Writable(
write(chunk, encoding, callback)
if (chunk.toString().indexOf('a') >= 0)
callback(new Error('chunk is invalid'));
else
callback();
);
const Writable = require('stream');
class MyWritable extends Writable
_write(chunk, encoding, callback)
if (chunk.toString().indexOf('a') >= 0)
callback(new Error('chunk is invalid'));
else
callback();
【问题讨论】:
【参考方案1】:.write()
是可写流的消费者或用户调用以将数据写入流对象的调用。这是任何使用可写流的人都可以使用的公共接口。
._write()
是一个内部接口。它不应该由可写流的消费者或用户调用。它由特定类型的流对象的实现者提供,当需要将数据写入该流背后实际存在的任何存储时,它就会由流本身调用。 它是底层存储的流抽象的一部分。例如,如果您实现了一个表示写入串行端口的流对象,作为该流对象的实现者,您将不得不覆盖泛型_write()
并提供._write()
的实现,只要流基础设施碰巧调用_write()
,它就会将字节物理地发送到串行端口。
请注意,在流对象的使用者调用.write()
和流基础设施随后调用._write()
之间没有一对一的对应关系,因为在流对象中进行了缓冲。
此设计还允许您拥有一个通用流接口,该接口下可以有数千种不同的实际存储机制,其中提供._write()
方法是实现存储接口的一部分,以便为其提供通用流接口存储。
并且,在您的第一个代码示例中,将选项对象中的write
属性提供给流构造函数实际上是提供_write()
的实现。构造函数将采用该函数并将其设为_write()
方法。是的,这令人困惑。
在第二个示例中,您直接覆盖了一个方法,因此您必须覆盖 _write()
方法,因为这是实现者必须提供的。
【讨论】:
这是不正确的。有两种方法可以创建Writable
。一种方法是扩展类并实现_write
方法。另一种是通过Writable
构造函数,它接受一个选项对象,其中一个是write
。在内部,它执行if (options.write) this._write = options.write
。 nodejs.org/api/stream.html#stream_simplified_constructiongithub.com/nodejs/node/blob/…
@erich2k8 - 是的,你是对的。我已经修改了答案以删除不正确的部分。实际上回答了 OP 关于_write()
和write()
之间区别的问题的操作部分仍然是正确的。我添加了最后两段以尝试进一步澄清。以上是关于Node.js 可写流:write vs _write的主要内容,如果未能解决你的问题,请参考以下文章