From 6d3920d579a3dc3a1e15875a15fb54e3ff4201c0 Mon Sep 17 00:00:00 2001 From: Khoo Hao Yit <40757009+KhooHaoYit@users.noreply.github.com> Date: Thu, 17 Mar 2022 01:45:45 +0800 Subject: [PATCH] stream: do cleanup when iterator is destroyed PR-URL: https://github.com/nodejs/node/pull/42320 Reviewed-By: Robert Nagy Reviewed-By: Matteo Collina Reviewed-By: Nitzan Uziely Reviewed-By: Benjamin Gruenbaum Reviewed-By: James M Snell --- lib/internal/streams/readable.js | 5 ++++- .../test-stream-readable-async-iterators.js | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/internal/streams/readable.js b/lib/internal/streams/readable.js index 3fcd373cb1c708..4b7613fd13d081 100644 --- a/lib/internal/streams/readable.js +++ b/lib/internal/streams/readable.js @@ -1122,7 +1122,7 @@ async function* createAsyncIterator(stream, options) { stream.on('readable', next); let error; - eos(stream, { writable: false }, (err) => { + const cleanup = eos(stream, { writable: false }, (err) => { error = err ? aggregateTwoErrors(error, err) : null; callback(); callback = nop; @@ -1150,6 +1150,9 @@ async function* createAsyncIterator(stream, options) { (error === undefined || stream._readableState.autoDestroy) ) { destroyImpl.destroyer(stream, null); + } else { + stream.off('readable', next); + cleanup(); } } } diff --git a/test/parallel/test-stream-readable-async-iterators.js b/test/parallel/test-stream-readable-async-iterators.js index 87184662139ae5..e8b69612014ca5 100644 --- a/test/parallel/test-stream-readable-async-iterators.js +++ b/test/parallel/test-stream-readable-async-iterators.js @@ -789,6 +789,20 @@ async function tests() { } ); } + + // Check for dangling listeners + (async function() { + const readable = createReadable(); + const opts = { destroyOnReturn: false }; + while (readable.readable) { + // eslint-disable-next-line no-unused-vars + for await (const chunk of readable.iterator(opts)) { + break; + } + } + + assert.deepStrictEqual(readable.eventNames(), []); + })().then(common.mustCall()); } {