55 ArrayPrototypeShift,
66 Error,
77 ObjectPrototypeHasOwnProperty,
8+ SafeMap,
89 SafeWeakMap,
910} = primordials ;
1011
@@ -149,9 +150,10 @@ class PromiseRejectionHandledWarning extends Error {
149150const maybeUnhandledPromises = new SafeWeakMap ( ) ;
150151
151152/**
152- * @type {Promise[] }
153+ * Using a Mp causes the promise to be referenced at least for one tick.
154+ * @type {Map<Promise, PromiseInfo> }
153155 */
154- const pendingUnhandledRejections = [ ] ;
156+ let pendingUnhandledRejections = new SafeMap ( ) ;
155157
156158/**
157159 * @type {Array<{promise: Promise, warning: Error}> }
@@ -279,21 +281,23 @@ const emitUnhandledRejection = (promise, promiseInfo) => {
279281 * @param {Error } reason
280282 */
281283function unhandledRejection ( promise , reason ) {
282- maybeUnhandledPromises . set ( promise , {
284+ pendingUnhandledRejections . set ( promise , {
283285 reason,
284286 uid : ++ lastPromiseId ,
285287 warned : false ,
286288 domain : process . domain ,
287289 } ) ;
288- // This causes the promise to be referenced at least for one tick.
289- ArrayPrototypePush ( pendingUnhandledRejections , promise ) ;
290290 setHasRejectionToWarn ( true ) ;
291291}
292292
293293/**
294294 * @param {Promise } promise
295295 */
296296function handledRejection ( promise ) {
297+ if ( pendingUnhandledRejections . has ( promise ) ) {
298+ pendingUnhandledRejections . delete ( promise ) ;
299+ return ;
300+ }
297301 const promiseInfo = maybeUnhandledPromises . get ( promise ) ;
298302 if ( promiseInfo !== undefined ) {
299303 maybeUnhandledPromises . delete ( promise ) ;
@@ -465,16 +469,17 @@ function processPromiseRejections() {
465469 }
466470 }
467471
468- let len = pendingUnhandledRejections . length ;
469472 let needPop = true ;
470473 let promiseAsyncId ;
471474
472- while ( len -- ) {
473- const promise = ArrayPrototypeShift ( pendingUnhandledRejections ) ;
474- const promiseInfo = maybeUnhandledPromises . get ( promise ) ;
475- if ( promiseInfo === undefined ) {
476- continue ;
477- }
475+ const pending = pendingUnhandledRejections ;
476+ pendingUnhandledRejections = new SafeMap ( ) ;
477+
478+ for ( const { 0 : promise , 1 : promiseInfo } of pending . entries ( ) ) {
479+ pending . delete ( promise ) ;
480+
481+ maybeUnhandledPromises . set ( promise , promiseInfo ) ;
482+
478483 promiseInfo . warned = true ;
479484
480485 // We need to check if async_hooks are enabled
@@ -499,7 +504,7 @@ function processPromiseRejections() {
499504 maybeScheduledTicksOrMicrotasks = true ;
500505 }
501506 return maybeScheduledTicksOrMicrotasks ||
502- pendingUnhandledRejections . length !== 0 ;
507+ pendingUnhandledRejections . size !== 0 ;
503508}
504509
505510function listenForRejections ( ) {
0 commit comments