@@ -18,6 +18,7 @@ const {
1818 Promise,
1919 PromisePrototypeThen,
2020 SafePromiseAllReturnVoid,
21+ SafeSet,
2122 Symbol,
2223 SymbolAsyncIterator,
2324 TypedArrayPrototypeGetBuffer,
@@ -451,6 +452,7 @@ function merge(...args) {
451452 // async tick per batch. Each source has at most one pending .next()
452453 // at a time. Every batch from every source is preserved.
453454 const ready = [ ] ;
455+ const pendingPulls = new SafeSet ( ) ;
454456 let activeCount = normalized . length ;
455457 let waitResolve = null ;
456458 let onAbort ;
@@ -472,6 +474,7 @@ function merge(...args) {
472474 // Called when a source's .next() settles. Pushes the result into
473475 // the ready queue and wakes the consumer if it's waiting.
474476 const onSettled = ( iterator , result ) => {
477+ pendingPulls . delete ( iterator ) ;
475478 if ( stopped ) return ;
476479 if ( result . done ) {
477480 activeCount -- ;
@@ -489,7 +492,8 @@ function merge(...args) {
489492 }
490493 } ;
491494
492- const onRejected = ( reason ) => {
495+ const onRejected = ( iterator , reason ) => {
496+ pendingPulls . delete ( iterator ) ;
493497 if ( stopped ) return ;
494498 ArrayPrototypePush ( ready , {
495499 __proto__ : null ,
@@ -507,14 +511,14 @@ function merge(...args) {
507511 for ( let i = 0 ; i < normalized . length ; i ++ ) {
508512 const iterator = normalized [ i ] [ SymbolAsyncIterator ] ( ) ;
509513 ArrayPrototypePush ( iterators , iterator ) ;
514+ pendingPulls . add ( iterator ) ;
510515 PromisePrototypeThen (
511516 iterator . next ( ) ,
512517 ( r ) => onSettled ( iterator , r ) ,
513- onRejected ,
518+ ( reason ) => onRejected ( iterator , reason ) ,
514519 ) ;
515520 }
516521
517- let completed = false ;
518522 let primaryError = kNoMergeError ;
519523 try {
520524 while ( activeCount > 0 || ready . length > 0 ) {
@@ -527,10 +531,11 @@ function merge(...args) {
527531 throw item . reason ;
528532 }
529533 yield item . value ;
534+ pendingPulls . add ( item . iterator ) ;
530535 PromisePrototypeThen (
531536 item . iterator . next ( ) ,
532537 ( r ) => onSettled ( item . iterator , r ) ,
533- onRejected ,
538+ ( reason ) => onRejected ( item . iterator , reason ) ,
534539 ) ;
535540 }
536541
@@ -545,7 +550,6 @@ function merge(...args) {
545550 } ) ;
546551 }
547552 }
548- completed = true ;
549553 } catch ( err ) {
550554 primaryError = err ;
551555 } finally {
@@ -559,20 +563,20 @@ function merge(...args) {
559563 await cleanupIterators (
560564 iterators ,
561565 primaryError ,
562- ! completed ,
566+ pendingPulls ,
563567 ) ;
564568 }
565569 } ,
566570 } ;
567571}
568572
569- async function cleanupIterators ( iterators , primaryError , skipAwaitCleanup ) {
573+ async function cleanupIterators ( iterators , primaryError , pendingPulls ) {
570574 let cleanupError = kNoMergeError ;
571575 await SafePromiseAllReturnVoid ( iterators , async ( iterator ) => {
572576 if ( iterator . return ) {
573577 try {
574578 const result = iterator . return ( ) ;
575- if ( skipAwaitCleanup ) {
579+ if ( pendingPulls . has ( iterator ) ) {
576580 markPromiseAsHandled ( result ) ;
577581 } else {
578582 await result ;
0 commit comments