5
5
ArrayPrototypeShift,
6
6
Error,
7
7
ObjectPrototypeHasOwnProperty,
8
+ SafeMap,
8
9
SafeWeakMap,
9
10
} = primordials ;
10
11
@@ -149,9 +150,10 @@ class PromiseRejectionHandledWarning extends Error {
149
150
const maybeUnhandledPromises = new SafeWeakMap ( ) ;
150
151
151
152
/**
152
- * @type {Promise[] }
153
+ * Using a Mp causes the promise to be referenced at least for one tick.
154
+ * @type {Map<Promise, PromiseInfo> }
153
155
*/
154
- const pendingUnhandledRejections = [ ] ;
156
+ let pendingUnhandledRejections = new SafeMap ( ) ;
155
157
156
158
/**
157
159
* @type {Array<{promise: Promise, warning: Error}> }
@@ -279,21 +281,23 @@ const emitUnhandledRejection = (promise, promiseInfo) => {
279
281
* @param {Error } reason
280
282
*/
281
283
function unhandledRejection ( promise , reason ) {
282
- maybeUnhandledPromises . set ( promise , {
284
+ pendingUnhandledRejections . set ( promise , {
283
285
reason,
284
286
uid : ++ lastPromiseId ,
285
287
warned : false ,
286
288
domain : process . domain ,
287
289
} ) ;
288
- // This causes the promise to be referenced at least for one tick.
289
- ArrayPrototypePush ( pendingUnhandledRejections , promise ) ;
290
290
setHasRejectionToWarn ( true ) ;
291
291
}
292
292
293
293
/**
294
294
* @param {Promise } promise
295
295
*/
296
296
function handledRejection ( promise ) {
297
+ if ( pendingUnhandledRejections . has ( promise ) ) {
298
+ pendingUnhandledRejections . delete ( promise ) ;
299
+ return ;
300
+ }
297
301
const promiseInfo = maybeUnhandledPromises . get ( promise ) ;
298
302
if ( promiseInfo !== undefined ) {
299
303
maybeUnhandledPromises . delete ( promise ) ;
@@ -465,16 +469,17 @@ function processPromiseRejections() {
465
469
}
466
470
}
467
471
468
- let len = pendingUnhandledRejections . length ;
469
472
let needPop = true ;
470
473
let promiseAsyncId ;
471
474
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
+
478
483
promiseInfo . warned = true ;
479
484
480
485
// We need to check if async_hooks are enabled
@@ -499,7 +504,7 @@ function processPromiseRejections() {
499
504
maybeScheduledTicksOrMicrotasks = true ;
500
505
}
501
506
return maybeScheduledTicksOrMicrotasks ||
502
- pendingUnhandledRejections . length !== 0 ;
507
+ pendingUnhandledRejections . size !== 0 ;
503
508
}
504
509
505
510
function listenForRejections ( ) {
0 commit comments