Readable stream documentation is unclear #14124
Description
The documentation makes it really unclear how to implement Readable streams.
Note: Implement this function, but do NOT call it directly.
This function should NOT be called directly. It should be implemented by child classes, and only called by the internal Readable class methods.
All Readable stream implementations must provide a _read method to fetch data from the underlying resource.
This method is prefixed with an underscore because it is internal to the class that defines it, and should not be called directly by user programs. However, you are expected to override this method in your own extension classes.
I get it, don't call read directly. Don't need to be told 4 separate times. This redundancy obscures the very small amount of useful information written about this method. Lets contract this into something less redundant like: "_Note: Implement this function, but do NOT call it directly. _This method is prefixed with an underscore because it is internal to the class that defines it and only the internal Readable class methods should call it. All Readable stream implementations must provide a read method to fetch data from the underlying resource."
When data is available, put it into the read queue by calling readable.push(chunk). If push returns false, then you should stop reading. When _read is called again, you should start pushing more data.
What in god's name does this mean about _read? This is documentation under the _read
method. Is it saying that the whole point of _read
is to indicate that the stream should pull from its data source after having stopped doing that? What is it talking about "again"? It never mentioned _read being called before that. When is _read
called initially?
Perhaps that paragraph should be changed to: "__read will be called [insert when read is first called here]. When the object stops reading as a result of push
returning false, the object should only continue reading from the resource when _read
is called again._"
What's the return value for _read? Nothing?
For push:
The _read() function will not be called again until at least one push(chunk) call is made.
Once again, the documentation refers to calling _read
"again" even tho it never mentions anything about calling it before. What does this mean?
The way the documentation describes things seems like a chicken and egg problem. _read
won't be called until push
is called (with something other than null), and push
shouldn't be called until a call to _read requests more data. How does this make sense?
How would I implement a simple passthrough that properly handles backpressure and all that? Would it be something like this?:
var Passthrough = function(stream, callback) {
Readable.call(this)
this.stream = stream
stream.on('readable', function() {
var data = stream.read()
if(data !== null) {
if(!this.push(data))
stream.pause()
}
}.bind(this))
stream.on('end', function() {
this.push(null)
}.bind(this))
}
util.inherits(StreamPeeker, Readable)
StreamPeeker.prototype._read = function() {
this.stream.resume()
}