77 Promise,
88 PromisePrototypeThen,
99 SymbolDispose,
10+ globalThis : { DisposableStack } ,
1011} = primordials ;
1112
1213const {
@@ -177,36 +178,38 @@ function eos(stream, options, callback) {
177178 callback . call ( stream ) ;
178179 } ;
179180
181+ const disposableStack = new DisposableStack ( ) ;
182+
180183 const onrequest = ( ) => {
181- stream . req . on ( 'finish' , onfinish ) ;
184+ disposableStack . use ( stream . req . addDisposableListener ( 'finish' , onfinish ) ) ;
182185 } ;
183186
184187 if ( isRequest ( stream ) ) {
185- stream . on ( 'complete' , onfinish ) ;
188+ disposableStack . use ( stream . addDisposableListener ( 'complete' , onfinish ) ) ;
186189 if ( ! willEmitClose ) {
187- stream . on ( 'abort' , onclose ) ;
190+ disposableStack . use ( stream . addDisposableListener ( 'abort' , onclose ) ) ;
188191 }
189192 if ( stream . req ) {
190193 onrequest ( ) ;
191194 } else {
192- stream . on ( 'request' , onrequest ) ;
195+ disposableStack . use ( stream . addDisposableListener ( 'request' , onrequest ) ) ;
193196 }
194197 } else if ( writable && ! wState ) { // legacy streams
195- stream . on ( 'end' , onlegacyfinish ) ;
196- stream . on ( 'close' , onlegacyfinish ) ;
198+ disposableStack . use ( stream . addDisposableListener ( 'end' , onlegacyfinish ) ) ;
199+ disposableStack . use ( stream . addDisposableListener ( 'close' , onlegacyfinish ) ) ;
197200 }
198201
199202 // Not all streams will emit 'close' after 'aborted'.
200203 if ( ! willEmitClose && typeof stream . aborted === 'boolean' ) {
201- stream . on ( 'aborted' , onclose ) ;
204+ disposableStack . use ( stream . addDisposableListener ( 'aborted' , onclose ) ) ;
202205 }
203206
204- stream . on ( 'end' , onend ) ;
205- stream . on ( 'finish' , onfinish ) ;
207+ disposableStack . use ( stream . addDisposableListener ( 'end' , onend ) ) ;
208+ disposableStack . use ( stream . addDisposableListener ( 'finish' , onfinish ) ) ;
206209 if ( options . error !== false ) {
207- stream . on ( 'error' , onerror ) ;
210+ disposableStack . use ( stream . addDisposableListener ( 'error' , onerror ) ) ;
208211 }
209- stream . on ( 'close' , onclose ) ;
212+ disposableStack . use ( stream . addDisposableListener ( 'close' , onclose ) ) ;
210213
211214 if ( closed ) {
212215 process . nextTick ( onclose ) ;
@@ -233,18 +236,10 @@ function eos(stream, options, callback) {
233236
234237 const cleanup = ( ) => {
235238 callback = nop ;
236- stream . removeListener ( 'aborted' , onclose ) ;
237- stream . removeListener ( 'complete' , onfinish ) ;
238- stream . removeListener ( 'abort' , onclose ) ;
239- stream . removeListener ( 'request' , onrequest ) ;
240- if ( stream . req ) stream . req . removeListener ( 'finish' , onfinish ) ;
241- stream . removeListener ( 'end' , onlegacyfinish ) ;
242- stream . removeListener ( 'close' , onlegacyfinish ) ;
243- stream . removeListener ( 'finish' , onfinish ) ;
244- stream . removeListener ( 'end' , onend ) ;
245- stream . removeListener ( 'error' , onerror ) ;
246- stream . removeListener ( 'close' , onclose ) ;
239+ disposableStack . dispose ( ) ;
247240 } ;
241+ // Arrange for the cleanup function to call itself when disposed.
242+ cleanup [ SymbolDispose ] = cleanup ;
248243
249244 if ( options . signal && ! closed ) {
250245 const abort = ( ) => {
0 commit comments