Node.js 可写流:write 与 _write

Node.js Writable stream: write vs _write

我正在阅读官方 Node.js 文档以了解流。我正在实现可写流,但我无法理解 write_write.

之间的区别

引用 this 部分的文档:

All calls to writable.write() that occur between the time writable._write() is called and the callback is called will cause the written data to be buffered. When the callback is invoked, the stream might emit a 'drain' event. If a stream implementation is capable of processing multiple chunks of data at once, the writable._writev() method should be implemented.

这只让我觉得两者的行为不同,但我不明白这是怎么回事。

可能是基于文档中 here 的示例,谁能解释下面给出的代码片段在从 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();
    }
  }
}

.write() 是可写流的消费者或用户将数据写入流对象所调用的。这是一个 public 接口,任何人都可以使用 使用 可写流。

._write()是内部接口。它不应该被可写流的消费者或用户调用。它 由特定类型的流对象的实现者 提供,每当需要将数据写入实际位于该流后面的任何存储时,它都会由流本身调用。 它是底层存储的流抽象的一部分。例如,如果您实现了一个表示写入串行端口的流对象,作为该流对象的实现者,您必须覆盖通用 _write() 并提供 ._write() 的实现,只要流基础结构恰好调用 _write().

,它就会物理地将字节发送到串行端口

请注意,由于流对象中的缓冲,流对象的使用者调用 .write() 和流基础结构随后调用 ._write() 之间没有一对一的对应关系.

这种设计还允许您拥有一个通用的流接口,该接口下面可以有数千种不同的实际存储机制,其中提供 ._write() 方法是实现存储接口的一部分,以便提供通用的该存储的流接口。


并且,在您的第一个代码示例中,在选项对象中向流构造函数提供 write 属性 实际上是为 _write() 提供实现。构造函数将采用该函数并将其设为 _write() 方法。是的,这令人困惑。

在您的第二个示例中,您直接覆盖了一个方法,因此您必须覆盖 _write() 方法,因为这是实现者必须提供的方法。