Reputation: 4353
Consider this Readable stream:
class ReadableStream extends stream.Readable {
constructor() {
super({objectMode:true, highWaterMark:128});
}
i = 0;
_read(size: number) {
while (this.push({key:this.i++})){}
}
}
Piping to process.stdout doesn't drain it automatically. Nothing happens, and the program exits.
new ReadableStream().pipe(process.stdout);
Now, let's pipe it to this Writable stream instead:
class WritableStream extends stream.Writable {
constructor() {
super({objectMode:true, highWaterMark:128});
}
_write(chunk: any, encoding: string, callback: (error?: (Error | null)) => void) {
console.log(chunk);
callback();
}
}
new ReadableStream().pipe(new WritableStream());
The console is instantly filled with numbers, and so it goes into infinity.
Why process.stdout or fs.createWriteStream do automatically request data?
Upvotes: 0
Views: 1167
Reputation: 707238
process.stdout
is not an object mode stream and does not work properly when you pipe an object mode stream to it. If you change your readableStream to not be an object mode stream, then the .pipe()
will work properly.
In fact, if you attach an event handler for the error
event such as:
new ReadableStream().pipe(process.stdout).on('error', err => {
console.log(err);
});
Then, you will get this:
TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be one of type string or Buffer. Received type object
at validChunk (_stream_writable.js:268:10)
at WriteStream.Writable.write (_stream_writable.js:303:21)
at ReadableStream.ondata (_stream_readable.js:727:22)
at ReadableStream.emit (events.js:210:5)
at ReadableStream.Readable.read (_stream_readable.js:525:10)
at flow (_stream_readable.js:1000:34)
at resume_ (_stream_readable.js:981:3)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
code: 'ERR_INVALID_ARG_TYPE'
}
Which shows that stdout is not expecting to get an object.
Upvotes: 2