@@ -18,6 +18,7 @@ const {
1818 Promise,
1919 PromisePrototypeThen,
2020 SafePromiseAllReturnVoid,
21+ SafeSet,
2122 Symbol,
2223 SymbolAsyncIterator,
2324 TypedArrayPrototypeGetBuffer,
@@ -440,6 +441,7 @@ function merge(...args) {
440441 // async tick per batch. Each source has at most one pending .next()
441442 // at a time. Every batch from every source is preserved.
442443 const ready = [ ] ;
444+ const pendingPulls = new SafeSet ( ) ;
443445 let activeCount = normalized . length ;
444446 let waitResolve = null ;
445447 let onAbort ;
@@ -461,6 +463,7 @@ function merge(...args) {
461463 // Called when a source's .next() settles. Pushes the result into
462464 // the ready queue and wakes the consumer if it's waiting.
463465 const onSettled = ( iterator , result ) => {
466+ pendingPulls . delete ( iterator ) ;
464467 if ( stopped ) return ;
465468 if ( result . done ) {
466469 activeCount -- ;
@@ -478,7 +481,8 @@ function merge(...args) {
478481 }
479482 } ;
480483
481- const onRejected = ( reason ) => {
484+ const onRejected = ( iterator , reason ) => {
485+ pendingPulls . delete ( iterator ) ;
482486 if ( stopped ) return ;
483487 ArrayPrototypePush ( ready , {
484488 __proto__ : null ,
@@ -496,14 +500,14 @@ function merge(...args) {
496500 for ( let i = 0 ; i < normalized . length ; i ++ ) {
497501 const iterator = normalized [ i ] [ SymbolAsyncIterator ] ( ) ;
498502 ArrayPrototypePush ( iterators , iterator ) ;
503+ pendingPulls . add ( iterator ) ;
499504 PromisePrototypeThen (
500505 iterator . next ( ) ,
501506 ( r ) => onSettled ( iterator , r ) ,
502- onRejected ,
507+ ( reason ) => onRejected ( iterator , reason ) ,
503508 ) ;
504509 }
505510
506- let completed = false ;
507511 let primaryError = kNoMergeError ;
508512 try {
509513 while ( activeCount > 0 || ready . length > 0 ) {
@@ -516,10 +520,11 @@ function merge(...args) {
516520 throw item . reason ;
517521 }
518522 yield item . value ;
523+ pendingPulls . add ( item . iterator ) ;
519524 PromisePrototypeThen (
520525 item . iterator . next ( ) ,
521526 ( r ) => onSettled ( item . iterator , r ) ,
522- onRejected ,
527+ ( reason ) => onRejected ( item . iterator , reason ) ,
523528 ) ;
524529 }
525530
@@ -534,7 +539,6 @@ function merge(...args) {
534539 } ) ;
535540 }
536541 }
537- completed = true ;
538542 } catch ( err ) {
539543 primaryError = err ;
540544 } finally {
@@ -548,20 +552,20 @@ function merge(...args) {
548552 await cleanupIterators (
549553 iterators ,
550554 primaryError ,
551- ! completed ,
555+ pendingPulls ,
552556 ) ;
553557 }
554558 } ,
555559 } ;
556560}
557561
558- async function cleanupIterators ( iterators , primaryError , skipAwaitCleanup ) {
562+ async function cleanupIterators ( iterators , primaryError , pendingPulls ) {
559563 let cleanupError = kNoMergeError ;
560564 await SafePromiseAllReturnVoid ( iterators , async ( iterator ) => {
561565 if ( iterator . return ) {
562566 try {
563567 const result = iterator . return ( ) ;
564- if ( skipAwaitCleanup ) {
568+ if ( pendingPulls . has ( iterator ) ) {
565569 markPromiseAsHandled ( result ) ;
566570 } else {
567571 await result ;
0 commit comments