diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index eb7d5011d49de2..afb25e6e84cd18 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -302,6 +302,8 @@ function readableAddChunk(stream, chunk, encoding, addToFront) { } } else if (!addToFront) { state.reading = false; + if (state.needReadable) + emitReadable(stream); maybeReadMore(stream, state); } } @@ -593,9 +595,12 @@ function emitReadable_(stream) { debug('emitReadable_', state.destroyed, state.length, state.ended); if (!state.destroyed && (state.length || state.ended)) { stream.emit('readable'); - state.emittedReadable = false; } + // Reset emittedReadable once it is safe to schedule another + // emitReadable. + state.emittedReadable = false; + // The stream needs another readable event if // 1. It is not flowing, as the flow mechanism will take // care of it. diff --git a/test/parallel/test-stream-duplex-empty-chunk.js b/test/parallel/test-stream-duplex-empty-chunk.js new file mode 100644 index 00000000000000..2977b5bff8b0cc --- /dev/null +++ b/test/parallel/test-stream-duplex-empty-chunk.js @@ -0,0 +1,19 @@ +'use strict'; + +const common = require('../common'); +const makeDuplexPair = require('../common/duplexpair'); + +const { clientSide, serverSide } = makeDuplexPair(); + +serverSide.resume(); +serverSide.on('end', function(buf) { + serverSide.write('out'); + serverSide.write(''); + serverSide.write(''); + serverSide.end(); +}); + +clientSide.end(); + +clientSide.on('data', common.mustCall()); +clientSide.on('end', common.mustCall()); diff --git a/test/parallel/test-stream2-compatibility.js b/test/parallel/test-stream2-compatibility.js index bd0314ec1a9918..43cabbc7675d15 100644 --- a/test/parallel/test-stream2-compatibility.js +++ b/test/parallel/test-stream2-compatibility.js @@ -44,7 +44,7 @@ class TestReader extends R { } const reader = new TestReader(); -setImmediate(function() { +process.nextTick(function() { assert.strictEqual(ondataCalled, 1); console.log('ok'); reader.push(null);