@@ -4,6 +4,7 @@ var IS_PURE = require('../internals/is-pure');
4
4
var global = require ( '../internals/global' ) ;
5
5
var getBuiltIn = require ( '../internals/get-built-in' ) ;
6
6
var call = require ( '../internals/function-call' ) ;
7
+ var uncurryThis = require ( '../internals/function-uncurry-this' ) ;
7
8
var NativePromise = require ( '../internals/native-promise-constructor' ) ;
8
9
var redefine = require ( '../internals/redefine' ) ;
9
10
var redefineAll = require ( '../internals/redefine-all' ) ;
@@ -43,6 +44,7 @@ var PromisePrototype = NativePromisePrototype;
43
44
var TypeError = global . TypeError ;
44
45
var document = global . document ;
45
46
var process = global . process ;
47
+ var push = uncurryThis ( [ ] . push ) ;
46
48
var newPromiseCapability = newPromiseCapabilityModule . f ;
47
49
var newGenericPromiseCapability = newPromiseCapability ;
48
50
@@ -95,47 +97,50 @@ var isThenable = function (it) {
95
97
return isObject ( it ) && isCallable ( then = it . then ) ? then : false ;
96
98
} ;
97
99
100
+ var callReaction = function ( reaction , state ) {
101
+ var value = state . value ;
102
+ var ok = state . state == FULFILLED ;
103
+ var handler = ok ? reaction . ok : reaction . fail ;
104
+ var resolve = reaction . resolve ;
105
+ var reject = reaction . reject ;
106
+ var domain = reaction . domain ;
107
+ var result , then , exited ;
108
+ try {
109
+ if ( handler ) {
110
+ if ( ! ok ) {
111
+ if ( state . rejection === UNHANDLED ) onHandleUnhandled ( state ) ;
112
+ state . rejection = HANDLED ;
113
+ }
114
+ if ( handler === true ) result = value ;
115
+ else {
116
+ if ( domain ) domain . enter ( ) ;
117
+ result = handler ( value ) ; // can throw
118
+ if ( domain ) {
119
+ domain . exit ( ) ;
120
+ exited = true ;
121
+ }
122
+ }
123
+ if ( result === reaction . promise ) {
124
+ reject ( TypeError ( 'Promise-chain cycle' ) ) ;
125
+ } else if ( then = isThenable ( result ) ) {
126
+ call ( then , result , resolve , reject ) ;
127
+ } else resolve ( result ) ;
128
+ } else reject ( value ) ;
129
+ } catch ( error ) {
130
+ if ( domain && ! exited ) domain . exit ( ) ;
131
+ reject ( error ) ;
132
+ }
133
+ } ;
134
+
98
135
var notify = function ( state , isReject ) {
99
136
if ( state . notified ) return ;
100
137
state . notified = true ;
101
- var chain = state . reactions ;
102
138
microtask ( function ( ) {
103
- var value = state . value ;
104
- var ok = state . state == FULFILLED ;
139
+ var chain = state . reactions ;
105
140
var index = 0 ;
106
141
// variable length - can't use forEach
107
142
while ( chain . length > index ) {
108
- var reaction = chain [ index ++ ] ;
109
- var handler = ok ? reaction . ok : reaction . fail ;
110
- var resolve = reaction . resolve ;
111
- var reject = reaction . reject ;
112
- var domain = reaction . domain ;
113
- var result , then , exited ;
114
- try {
115
- if ( handler ) {
116
- if ( ! ok ) {
117
- if ( state . rejection === UNHANDLED ) onHandleUnhandled ( state ) ;
118
- state . rejection = HANDLED ;
119
- }
120
- if ( handler === true ) result = value ;
121
- else {
122
- if ( domain ) domain . enter ( ) ;
123
- result = handler ( value ) ; // can throw
124
- if ( domain ) {
125
- domain . exit ( ) ;
126
- exited = true ;
127
- }
128
- }
129
- if ( result === reaction . promise ) {
130
- reject ( TypeError ( 'Promise-chain cycle' ) ) ;
131
- } else if ( then = isThenable ( result ) ) {
132
- call ( then , result , resolve , reject ) ;
133
- } else resolve ( result ) ;
134
- } else reject ( value ) ;
135
- } catch ( error ) {
136
- if ( domain && ! exited ) domain . exit ( ) ;
137
- reject ( error ) ;
138
- }
143
+ callReaction ( chain [ index ++ ] , state ) ;
139
144
}
140
145
state . reactions = [ ] ;
141
146
state . notified = false ;
@@ -265,14 +270,15 @@ if (FORCED) {
265
270
// https://tc39.es/ecma262/#sec-promise.prototype.then
266
271
then : function then ( onFulfilled , onRejected ) {
267
272
var state = getInternalPromiseState ( this ) ;
268
- var reactions = state . reactions ;
269
273
var reaction = newPromiseCapability ( speciesConstructor ( this , PromiseConstructor ) ) ;
274
+ state . parent = true ;
270
275
reaction . ok = isCallable ( onFulfilled ) ? onFulfilled : true ;
271
276
reaction . fail = isCallable ( onRejected ) && onRejected ;
272
277
reaction . domain = IS_NODE ? process . domain : undefined ;
273
- state . parent = true ;
274
- reactions [ reactions . length ] = reaction ;
275
- if ( state . state != PENDING ) notify ( state , false ) ;
278
+ if ( state . state == PENDING ) push ( state . reactions , reaction ) ;
279
+ else microtask ( function ( ) {
280
+ callReaction ( reaction , state ) ;
281
+ } ) ;
276
282
return reaction . promise ;
277
283
} ,
278
284
// `Promise.prototype.catch` method
0 commit comments