简体   繁体   English

Node.js 可写 stream:写 vs _write

[英]Node.js Writable stream: write vs _write

I'm reading official Node.js docs to understand streams.我正在阅读官方 Node.js 文档以了解流。 I'm implementing Writable stream, but I can't understand what is the difference between write and _write .我正在实现 Writable stream,但我无法理解write_write之间的区别。

Quoting the docs from this section:引用节中的文档:

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.在调用 writable._write() 和调用回调之间发生的所有对 writable.write() 的调用都会导致写入的数据被缓冲。 When the callback is invoked, the stream might emit a 'drain' event.调用回调时,stream 可能会发出“耗尽”事件。 If a stream implementation is capable of processing multiple chunks of data at once, the writable._writev() method should be implemented.如果 stream 实现能够一次处理多个数据块,则应实现 writable._writev() 方法。

this only gives me the idea that both behave differently, but I can't understand how.这只会让我觉得两者的行为不同,但我不明白如何。

May be by taking an example based on here in the docs, can anyone explain what is the difference in the ways the code snippets given below will behave on receiving data from Readable/Transform stream?可能是基于文档中的 此处示例,任何人都可以解释下面给出的代码片段在从Readable/Transform stream 接收数据时的行为方式有何不同? What are write and _write counterparts in Readable stream, if any? Readable stream 中的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() is what the consumer or user of a writable stream calls to write data to the stream object. This is a public interface expected to be used by anyone using a writable stream. .write()是可写 stream 的消费者或用户将数据写入 stream object 的调用。这是一个公共接口,预计任何使用可写 stream 的人都可以使用。

._write() is an internal interface. ._write()是一个内部接口。 It should NOT be called by the consumer or user of a writable stream. It is supplied by the implementer of the specific type of stream object and it will be called by the stream itself whenever data needs to be written to whatever storage is actually behind this stream. It's part of the stream abstraction for the underlying storage.它不应该由可写 stream 的消费者或用户调用。它由 stream object 的特定类型的实现者提供,并且当数据需要写入实际背后的任何存储时,stream 本身将调用它stream。它是底层存储的 stream 抽象的一部分。 For example, if you implemented a stream object that represents writing to a serial port, as the implementer of that stream object, you would have to override the generic _write() and supply an implementation of ._write() that physically send bytes to the serial port whenever the stream infrastructure happens to call _write() .例如,如果您实现了表示写入串口的 stream object,作为该 stream object 的实现者,您必须覆盖通用_write()并提供._write()的实现,该实现将字节物理发送到每当 stream 基础结构恰好调用_write()时,串行端口。

Note, there is not a 1-to-1 correspondence between when the consumer of the stream object calls .write() and when the stream infrastructure then calls ._write() because of buffering within the stream object.注意,在 stream object 的消费者调用.write()和 stream 基础设施随后调用._write()之间没有一对一的对应关系,因为在 stream object 中进行缓冲。

This design also allows you to have one common stream interface that can have thousands of different actual storage mechanisms beneath it where supplying a ._write() method is one part of implementing a storage interface in order to offer a generic stream interface to that storage.这种设计还允许您拥有一个通用的 stream 接口,该接口下面可以有数千种不同的实际存储机制,其中提供._write()方法是实现存储接口的一部分,以便为该存储提供通用的 stream 接口。


And, in your first code example, supplying a write property in the option object to the stream constructor is actually providing an implementation for _write() .而且,在您的第一个代码示例中,在选项 object 中向 stream 构造函数提供write属性实际上是为_write()提供实现。 The constructor will take that function and make it the _write() method.构造函数将采用 function 并将其设为_write()方法。 Yes, this is confusing.是的,这令人困惑。

In your second example, you're overriding a method directly so you have to override the _write() method because that's the one that implementors must provide.在你的第二个例子中,你直接重写了一个方法,所以你必须重写_write()方法,因为这是实现者必须提供的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM