summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/_stream_readable.js4
-rw-r--r--test/parallel/test-stream-readable-no-unneeded-readable.js39
2 files changed, 42 insertions, 1 deletions
diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js
index 9cf786a15b..364f2ba744 100644
--- a/lib/_stream_readable.js
+++ b/lib/_stream_readable.js
@@ -520,7 +520,9 @@ function emitReadable(stream) {
function emitReadable_(stream) {
var state = stream._readableState;
debug('emit readable');
- stream.emit('readable');
+ if (!state.destroyed && (state.length || state.ended)) {
+ stream.emit('readable');
+ }
state.needReadable = !state.flowing && !state.ended;
flow(stream);
}
diff --git a/test/parallel/test-stream-readable-no-unneeded-readable.js b/test/parallel/test-stream-readable-no-unneeded-readable.js
new file mode 100644
index 0000000000..bd3e06e5f7
--- /dev/null
+++ b/test/parallel/test-stream-readable-no-unneeded-readable.js
@@ -0,0 +1,39 @@
+'use strict';
+const common = require('../common');
+const { Readable, PassThrough } = require('stream');
+
+const source = new Readable({
+ read: () => {}
+});
+
+source.push('foo');
+source.push('bar');
+source.push(null);
+
+const pt = source.pipe(new PassThrough());
+
+const wrapper = new Readable({
+ read: () => {
+ let data = pt.read();
+
+ if (data) {
+ wrapper.push(data);
+ return;
+ }
+
+ pt.once('readable', function() {
+ data = pt.read();
+ if (data) {
+ wrapper.push(data);
+ }
+ // else the end event should fire
+ });
+ }
+});
+
+pt.once('end', function() {
+ wrapper.push(null);
+});
+
+wrapper.resume();
+wrapper.once('end', common.mustCall());