两种读取模式
Readable
流以两种模式之一有效地运行:流动和暂停。
这些模式与对象模式是分开的。
Readable
流可以处于或不处于对象模式,无论其是处于流动模式还是暂停模式。
-
在流动模式下,数据会自动从底层系统读取,并通过
EventEmitter
接口使用事件尽快提供给应用程序。 -
在暂停模式下,必须显式调用
stream.read()
方法以从流中读取数据块。
所有的 Readable
流都以暂停模式开始,但可以通过以下方式之一切换到流动模式:
- 添加
'data'
事件句柄。 - 调用
stream.resume()
方法。 - 调用
stream.pipe()
方法将数据发送到Writable
。
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:
- Adding a
'data'
event handler. - Calling the
stream.resume()
method. - Calling the
stream.pipe()
method to send the data to aWritable
.
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.