Skip to content

Commit

Permalink
doc: clarify Readable paused/flowing!==object mode
Browse files Browse the repository at this point in the history
- Clarify that a `Readable` stream's reading mode (paused vs. flowing)
  is independent of its object mode (object vs. non-object).  I am
  relatively new to Node streams, and was briefly confused while
  reading the docs by the two uses of the word "mode".

- Copyediting: add missing apostrophes; minor grammatical changes
  • Loading branch information
cxw42 authored and Chris White committed Aug 31, 2018
1 parent 030ef35 commit 0bb51b0
Showing 1 changed file with 22 additions and 18 deletions.
40 changes: 22 additions & 18 deletions doc/api/stream.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ buffer that can be retrieved using `writable.writableBuffer` or
`readable.readableBuffer`, respectively.

The amount of data potentially buffered depends on the `highWaterMark` option
passed into the streams constructor. For normal streams, the `highWaterMark`
passed into the stream's constructor. For normal streams, the `highWaterMark`
option specifies a [total number of bytes][hwm-gotcha]. For streams operating
in object mode, the `highWaterMark` specifies a total number of objects.

Expand Down Expand Up @@ -576,15 +576,18 @@ Examples of `Readable` streams include:
All [`Readable`][] streams implement the interface defined by the
`stream.Readable` class.

#### Two Modes
#### Two Reading Modes

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

When in flowing mode, data is read from the underlying system automatically
* 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()`][stream-read] method must be called
* In paused mode, the [`stream.read()`][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
Expand Down Expand Up @@ -633,22 +636,22 @@ within the `Readable` stream implementation.
Specifically, at any given point in time, every `Readable` is in one of three
possible states:

* `readable.readableFlowing = null`
* `readable.readableFlowing = false`
* `readable.readableFlowing = true`
* `readable.readableFlowing === null`
* `readable.readableFlowing === false`
* `readable.readableFlowing === true`

When `readable.readableFlowing` is `null`, no mechanism for consuming the
streams data is provided so the stream will not generate its data. While in this
state, attaching a listener for the `'data'` event, calling the
stream's data is provided. Therefore, the stream will not generate data.
While in this state, attaching a listener for the `'data'` event, calling the
`readable.pipe()` method, or calling the `readable.resume()` method will switch
`readable.readableFlowing` to `true`, causing the `Readable` to begin
actively emitting events as data is generated.
`readable.readableFlowing` to `true`, causing the `Readable` to begin actively
emitting events as data is generated.

Calling `readable.pause()`, `readable.unpipe()`, or receiving backpressure
will cause the `readable.readableFlowing` to be set as `false`,
temporarily halting the flowing of events but *not* halting the generation of
data. While in this state, attaching a listener for the `'data'` event
would not cause `readable.readableFlowing` to switch to `true`.
will not switch `readable.readableFlowing` to `true`.

```js
const { PassThrough, Writable } = require('stream');
Expand All @@ -660,20 +663,20 @@ pass.unpipe(writable);
// readableFlowing is now false

pass.on('data', (chunk) => { console.log(chunk.toString()); });
pass.write('ok'); // will not emit 'data'
pass.resume(); // must be called to make 'data' being emitted
pass.write('ok'); // will not emit 'data'
pass.resume(); // must be called to make stream emit 'data'
```

While `readable.readableFlowing` is `false`, data may be accumulating
within the streams internal buffer.
within the stream's internal buffer.

#### Choose One
#### Choose One API Style

The `Readable` stream API evolved across multiple Node.js versions and provides
multiple methods of consuming stream data. In general, developers should choose
*one* of the methods of consuming data and *should never* use multiple methods
to consume data from a single stream. Specifically, using a combination
of `on('data')`, `on('readable')`, `pipe()` or async iterators could
of `on('data')`, `on('readable')`, `pipe()`, or async iterators could
lead to unintuitive behavior.

Use of the `readable.pipe()` method is recommended for most users as it has been
Expand Down Expand Up @@ -2478,3 +2481,4 @@ contain multi-byte characters.
[readable-destroy]: #stream_readable_destroy_error
[writable-_destroy]: #stream_writable_destroy_err_callback
[writable-destroy]: #stream_writable_destroy_error
[object-mode]: #stream_object_mode

0 comments on commit 0bb51b0

Please sign in to comment.