两种读取模式


Readable 流以两种模式之一有效地运行:流动和暂停。 这些模式与对象模式是分开的。 Readable 流可以处于或不处于对象模式,无论其是处于流动模式还是暂停模式。

  • 在流动模式下,数据会自动从底层系统读取,并通过 EventEmitter 接口使用事件尽快提供给应用程序。

  • 在暂停模式下,必须显式调用 stream.read() 方法以从流中读取数据块。

所有的 Readable 流都以暂停模式开始,但可以通过以下方式之一切换到流动模式:

Readable 可以使用以下方法之一切换回暂停模式:

  • 如果没有管道目标,则通过调用 stream.pause() 方法。
  • 如果有管道目标,则删除所有管道目标。 可以通过调用 stream.unpipe() 方法删除多个管道目标。

要记住的重要概念是,在提供消费或忽略该数据的机制之前,Readable 不会产生数据。 如果消费机制被禁用或移除,则 Readable 将尝试停止产生数据。

出于向后兼容性的原因,删除 'data' 事件句柄不会自动暂停流。 此外,如果有管道目标,则调用 stream.pause() 将不能保证一旦这些目标排空并要求更多数据,流将保持暂停状态。

如果 Readable 切换到流动模式并且没有消费者可用于处理数据,则数据将被丢失。 例如,当调用 readable.resume() 方法而没有绑定到 'data' 事件的监听器时,或者当从流中删除 'data' 事件句柄时,就会发生这种情况。

添加 'readable' 事件句柄会自动使流停止流动,并且必须通过 readable.read() 来消费数据。 如果删除了 'readable' 事件句柄,则如果有 'data' 事件句柄,流将再次开始流动。

Readable streams effectively operate in one of two modes: flowing and paused. These modes are separate from object mode. A Readable stream can be in object mode or not, regardless of whether it is in flowing mode or paused mode.

  • In flowing mode, data is read from the underlying system automatically and provided to an application as quickly as possible using events via the EventEmitter interface.

  • In paused mode, the stream.read() method must be called explicitly to read chunks of data from the stream.

All Readable streams begin in paused mode but can be switched to flowing mode in one of the following ways:

The Readable can switch back to paused mode using one of the following:

  • If there are no pipe destinations, by calling the stream.pause() method.
  • If there are pipe destinations, by removing all pipe destinations. Multiple pipe destinations may be removed by calling the stream.unpipe() method.

The important concept to remember is that a Readable will not generate data until a mechanism for either consuming or ignoring that data is provided. If the consuming mechanism is disabled or taken away, the Readable will attempt to stop generating the data.

For backward compatibility reasons, removing 'data' event handlers will not automatically pause the stream. Also, if there are piped destinations, then calling stream.pause() will not guarantee that the stream will remain paused once those destinations drain and ask for more data.

If a Readable is switched into flowing mode and there are no consumers available to handle the data, that data will be lost. This can occur, for instance, when the readable.resume() method is called without a listener attached to the 'data' event, or when a 'data' event handler is removed from the stream.

Adding a 'readable' event handler automatically makes the stream stop flowing, and the data has to be consumed via readable.read(). If the 'readable' event handler is removed, then the stream will start flowing again if there is a 'data' event handler.