Node.js Readable流_read()未实现及read方法push无效问题咨询
Hey there, let's unpack your Node.js Readable stream confusion step by step—this is a super common gotcha when first working with custom streams!
First, let's clarify the _read() requirement
The initial error you saw (ERR_STREAM_READ_NOT_IMPLEMENTED) happens because all custom Readable streams require you to implement the _read() method (note the leading underscore—Node.js uses this to indicate internal methods, though you can pass it as read in the options object, which gets mapped to _read under the hood). This method is the stream's way of asking you for more data when it's ready to consume it.
Why pushing inside _read() didn't output anything
Here's the key: _read() isn't called automatically when you create the stream—it only gets triggered when the stream is in flowing mode (i.e., there's a consumer ready to handle the data).
In your code where you pushed 'foo' inside _read(), you didn't set up any way to consume the stream. Without a data event listener, a pipe() to another stream, or a manual call to resume(), the stream stays in paused mode. It never asks for data, so _read() never runs—meaning your push() never executes at all.
Why pushing from outside worked
When you call push() directly from outside the _read() method, you're manually adding data to the stream's internal buffer, regardless of whether the stream is in flowing mode. If you had a consumer set up, that data would be emitted immediately; even without one, the data sits in the buffer waiting to be consumed. But since you probably tested it with a consumer (like logging the output or piping to stdout), you saw the data show up.
The "no need to implement read()" myth
That claim only applies to pre-built Readable streams, not custom ones. For example:
- When you use
Readable.from(['foo', 'bar'])to create a stream from an iterable - When you use
fs.createReadStream()to read a file - Any other built-in Readable stream (like
process.stdin)
These streams already have their own _read() implementation baked in, so you don't need to write one. But for a completely custom Readable stream (like the one you're building), you must define _read() to tell the stream how to fetch data when it needs it.
A working example to see it in action
Let's fix your code to show how _read() is supposed to work. We'll add a consumer so the stream triggers _read():
import { Readable } from "stream"; this.readableStream = new Readable({ _read(size) { // This gets called automatically when the stream is ready for data this.push('foo'); // Push null to signal the stream has ended (optional) // setTimeout(() => this.push(null), 100); } }); // Add a consumer to trigger flowing mode this.readableStream.on('data', (chunk) => { console.log(chunk.toString()); // This will log 'foo' repeatedly until you push null }); // Alternatively, pipe to stdout: // this.readableStream.pipe(process.stdout);
Now when you run this, the data listener puts the stream into flowing mode, so _read() gets called, and your pushed 'foo' is logged to the console.
Quick recap
- Custom Readable streams need a
_read()method to tell the stream how to get data. _read()is only called when the stream is in flowing mode (has a consumer).- Pushing from outside adds data directly to the buffer, but you still need a consumer to see it.
- Pre-built streams handle
_read()for you—only custom ones need your implementation.
内容的提问来源于stack exchange,提问作者Alexander Mills

