Node.js Stream

どうやら Stream は Process を占有せずに chunk ごとに処理をできるようにするらしい。また、読み取り only であったり、書き込み only、読み書き okay、読み取ったデータを変換して出力もできるらしい。
refs: Node.js Stream を使いこなす

Stream
A stream is an abstract interface for working with streaming data in Node.js.
Streams can be readable, writable, or both. All streams are instances of EventEmitter.
Types of streams
Writable: streams to which data can be written.
Readable: streams from which data can be read.
Duplex: streams that are both Readable and Writable.
Transform: Duplex streams that can modify or transform the data as it is written and read.
Object mode
All streams created by Node.js APIs operate exclusively on strings and Buffer (or Uint8Array) objects. It is possible, however, for stream implementations to work with other types of JavaScript values (with the exception of null, which serves a special purpose within streams). Such streams are considered to operate in "object mode".
Stream instances are switched into object mode using the objectMode option when the stream is created. Attempting to switch an existing stream into object mode is not safe.
Buffering
Both Writable and Readable streams will store data in an internal buffer.
The amount of data potentially buffered depends on the highWaterMark option passed into the stream's constructor. For normal streams, the highWaterMark option specifies a total number of bytes. For streams operating in object mode, the highWaterMark specifies a total number of objects.
Data is buffered in Readable streams when the implementation calls stream.push(chunk). If the consumer of the Stream does not call stream.read(), the data will sit in the internal queue until it is consumed.
Once the total size of the internal read buffer reaches the threshold specified by highWaterMark, the stream will temporarily stop reading data from the underlying resource until the data currently buffered can be consumed (that is, the stream will stop calling the internal readable._read() method that is used to fill the read buffer).
Data is buffered in Writable streams when the writable.write(chunk) method is called repeatedly. While the total size of the internal write buffer is below the threshold set by highWaterMark, calls to writable.write() will return true. Once the size of the internal buffer reaches or exceeds the highWaterMark, false will be returned.
A key goal of the stream API, particularly the stream.pipe() method, is to limit the buffering of data to acceptable levels such that sources and destinations of differing speeds will not overwhelm the available memory.
The highWaterMark option is a threshold, not a limit: it dictates the amount of data that a stream buffers before it stops asking for more data. It does not enforce a strict memory limitation in general. Specific stream implementations may choose to enforce stricter limits but doing so is optional.
Because Duplex and Transform streams are both Readable and Writable, each maintains two separate internal buffers used for reading and writing, allowing each side to operate independently of the other while maintaining an appropriate and efficient flow of data. For example, net.Socket instances are Duplex streams whose Readable side allows consumption of data received from the socket and whose Writable side allows writing data to the socket. Because data may be written to the socket at a faster or slower rate than data is received, each side should operate (and buffer) independently of the other.
The mechanics of the internal buffering are an internal implementation detail and may be changed at any time. However, for certain advanced implementations, the internal buffers can be retrieved using writable.writableBuffer or readable.readableBuffer. Use of these undocumented properties is discouraged.
refs: Stream

Two reading modes
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 a Writable.
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.
Three states
The "two modes" of operation for a Readable stream are a simplified abstraction for the more complicated internal state management that is happening 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
When readable.readableFlowing is null, no mechanism for consuming 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.
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 will not switch readable.readableFlowing to true.
refs: Readable streams

Events
Much of the Node.js core API is built around an idiomatic asynchronous event-driven architecture in which certain kinds of objects (called "emitters") emit named events that cause Function objects ("listeners") to be called.
For instance: a net.Server object emits an event each time a peer connects to it; a fs.ReadStream emits an event when the file is opened; a stream emits an event whenever data is available to be read.
All objects that emit events are instances of the EventEmitter class. These objects expose an eventEmitter.on() function that allows one or more functions to be attached to named events emitted by the object. Typically, event names are camel-cased strings but any valid JavaScript property key can be used.
When the EventEmitter object emits an event, all of the functions attached to that specific event are called synchronously. Any values returned by the called listeners are ignored and discarded.
Node.js EventTarget vs. DOM EventTarget
There are two key differences between the Node.js EventTarget and the EventTarget Web API:
Whereas DOM EventTarget instances may be hierarchical, there is no concept of hierarchy and event propagation in Node.js. That is, an event dispatched to an EventTarget does not propagate through a hierarchy of nested target objects that may each have their own set of handlers for the event.
In the Node.js EventTarget, if an event listener is an async function or returns a Promise, and the returned Promise rejects, the rejection is automatically captured and handled the same way as a listener that throws synchronously (see EventTarget error handling for details).
NodeEventTarget vs. EventEmitter
The NodeEventTarget object implements a modified subset of the EventEmitter API that allows it to closely emulate an EventEmitter in certain situations. A NodeEventTarget is not an instance of EventEmitter and cannot be used in place of an EventEmitter in most cases.
Unlike EventEmitter, any given listener can be registered at most once per event type. Attempts to register a listener multiple times are ignored.
The NodeEventTarget does not emulate the full EventEmitter API. Specifically the prependListener(), prependOnceListener(), rawListeners(), setMaxListeners(), getMaxListeners(), and errorMonitor APIs are not emulated. The 'newListener' and 'removeListener' events will also not be emitted.
The NodeEventTarget does not implement any special default behavior for events with type 'error'.
The NodeEventTarget supports EventListener objects as well as functions as handlers for all event types.
refs: Events