stream: allow using .push()/.unshift() during once('data')

Previously, the `.push()` or `.unshift()` call would just have jumped
straight to emitting a `'data'` event, even if there were no listeners,
effectively just silently dropping the chunk.

PR-URL: https://github.com/nodejs/node/pull/34957
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Denys Otrishko <shishugi@gmail.com>
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: Ricky Zhou <0x19951125@gmail.com>
This commit is contained in:
Anna Henningsen authored and Rich Trott committed 2020-08-30 08:42:33 -07:00
1 parent 07e7ad941b
commit c1ef122e98
2 files changed
+23 -1

No files matched your search

+2 -1
View File
@@ -310,7 +310,8 @@ function readableAddChunk(stream, chunk, encoding, addToFront) {
}
function addChunk(stream, state, chunk, addToFront) {
if (state.flowing && state.length === 0 && !state.sync) {
if (state.flowing && state.length === 0 && !state.sync &&
stream.listenerCount('data') > 0) {
// Use the guard to avoid creating `Set()` repeatedly
// when we have multiple pipes.
if (state.multiAwaitDrain) {
@@ -0,0 +1,21 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const { Readable } = require('stream');
// Verify that .push() and .unshift() can be called from 'data' listeners.
for (const method of ['push', 'unshift']) {
const r = new Readable({ read() {} });
r.once('data', common.mustCall((chunk) => {
assert.strictEqual(r.readableLength, 0);
r[method](chunk);
assert.strictEqual(r.readableLength, chunk.length);
r.on('data', common.mustCall((chunk) => {
assert.strictEqual(chunk.toString(), 'Hello, world');
}));
}));
r.push('Hello, world');
}