Promise Resolve Functions
- A promise resolve function is an anonymous built-in function that has [[Promise]] and [[AlreadyResolved]] internal slots.
+ A promise resolve function is an anonymous built-in function that has [[Promise]], [[AlreadyResolved]] and [[FinallySourcePromise]] internal slots.
When a promise resolve function _F_ is called with argument _resolution_, the following steps are taken:
1. Assert: _F_ has a [[Promise]] internal slot whose value is an Object.
+ 1. Assert: _F_ has a [[FinallySourcePromise]] internal slot whose value is either a promise object with a [[PromiseState]] internal slot or *undefined*.
1. Let _promise_ be _F_.[[Promise]].
1. Let _alreadyResolved_ be _F_.[[AlreadyResolved]].
1. If _alreadyResolved_.[[Value]] is *true*, return *undefined*.
@@ -38577,15 +38579,22 @@ Promise Resolve Functions
1. If SameValue(_resolution_, _promise_) is *true*, then
1. Let _selfResolutionError_ be a newly created *TypeError* object.
1. Return RejectPromise(_promise_, _selfResolutionError_).
+ 1. Let _finallySourcePromise_ be _F_.[[FinallySourcePromise]].
1. If Type(_resolution_) is not Object, then
- 1. Return FulfillPromise(_promise_, _resolution_).
+ 1. If _finallySourcePromise_ is *undefined*
+ 1. Return FulfillPromise(_promise_, _resolution_).
+ 1. Else
+ 1. If _finallySourcePromise_.[[PromiseState]] is "rejected"
+ 1. Return RejectPromise(_promise_, _finallySourcePromise_.[[PromiseResult]]).
+ 1. Else
+ 1. Return FulfillPromise(_promise_, _finallySourcePromise_.[[PromiseResult]]).
1. Let _then_ be Get(_resolution_, `"then"`).
1. If _then_ is an abrupt completion, then
1. Return RejectPromise(_promise_, _then_.[[Value]]).
1. Let _thenAction_ be _then_.[[Value]].
1. If IsCallable(_thenAction_) is *false*, then
1. Return FulfillPromise(_promise_, _resolution_).
- 1. Perform EnqueueJob(`"PromiseJobs"`, PromiseResolveThenableJob, « _promise_, _resolution_, _thenAction_ »).
+ 1. Perform EnqueueJob(`"PromiseJobs"`, PromiseResolveThenableJob, « _promise_, _resolution_, _thenAction_, _finallySourcePromise_ »).
1. Return *undefined*.
The `length` property of a promise resolve function is 1.
@@ -38609,15 +38618,17 @@ FulfillPromise ( _promise_, _value_ )
- NewPromiseCapability ( _C_ )
- The abstract operation NewPromiseCapability takes a constructor function, and attempts to use that constructor function in the fashion of the built-in `Promise` constructor to create a Promise object and extract its resolve and reject functions. The promise plus the resolve and reject functions are used to initialize a new PromiseCapability Record which is returned as the value of this abstract operation.
+ NewPromiseCapability ( _C_ [ , _finallySourcePromise_ ] )
+ The abstract operation NewPromiseCapability takes a constructor function, and attempts to use that constructor function in the fashion of the built-in `Promise` constructor to create a Promise object and extract its resolve and reject functions. The promise plus the resolve and reject functions are used to initialize a new PromiseCapability Record which is returned as the value of this abstract operation. NewPromiseCapability also takes an optional _finallySourcePromise_, which is either a promise object with a [[PromiseState]] internal slot or *undefined*. If _finallySourcePromise_ is a promise object, it is the promise object on which `Promise.prototype.finally` () was invoked, during which NewPromiseCapability was performed in order to create the resulted promise.
1. If IsConstructor(_C_) is *false*, throw a *TypeError* exception.
1. NOTE: _C_ is assumed to be a constructor function that supports the parameter conventions of the `Promise` constructor (see ).
+ 1. If _finallySourcePromise_ is not present, set _finallySourcePromise_ to *undefined*.
1. Let _promiseCapability_ be a new PromiseCapability { [[Promise]]: *undefined*, [[Resolve]]: *undefined*, [[Reject]]: *undefined* }.
1. Let _steps_ be the algorithm steps defined in .
- 1. Let _executor_ be CreateBuiltinFunction(_steps_, « [[Capability]] »).
+ 1. Let _executor_ be CreateBuiltinFunction(_steps_, « [[Capability]] », « [[FinallySourcePromise]] »).
1. Set _executor_.[[Capability]] to _promiseCapability_.
+ 1. Set _executor_.[[FinallySourcePromise]] to _finallySourcePromise_.
1. Let _promise_ be ? Construct(_C_, « _executor_ »).
1. If IsCallable(_promiseCapability_.[[Resolve]]) is *false*, throw a *TypeError* exception.
1. If IsCallable(_promiseCapability_.[[Reject]]) is *false*, throw a *TypeError* exception.
@@ -38631,10 +38642,11 @@ NewPromiseCapability ( _C_ )
GetCapabilitiesExecutor Functions
- A GetCapabilitiesExecutor function is an anonymous built-in function that has a [[Capability]] internal slot.
+ A GetCapabilitiesExecutor function is an anonymous built-in function that has a [[Capability]] and a [[FinallySourcePromise]] internal slots.
When a GetCapabilitiesExecutor function _F_ is called with arguments _resolve_ and _reject_, the following steps are taken:
1. Assert: _F_ has a [[Capability]] internal slot whose value is a PromiseCapability Record.
+ 1. Assert: _F_ has a [[FinallySourcePromise]] internal slot whose value is either a promise object with a [[PromiseState]] internal slot or *undefined*.
1. Let _promiseCapability_ be _F_.[[Capability]].
1. If _promiseCapability_.[[Resolve]] is not *undefined*, throw a *TypeError* exception.
1. If _promiseCapability_.[[Reject]] is not *undefined*, throw a *TypeError* exception.
@@ -38737,10 +38749,10 @@ PromiseReactionJob ( _reaction_, _argument_ )
- PromiseResolveThenableJob ( _promiseToResolve_, _thenable_, _then_ )
- The job PromiseResolveThenableJob with parameters _promiseToResolve_, _thenable_, and _then_ performs the following steps:
+ PromiseResolveThenableJob ( _promiseToResolve_, _thenable_, _then_, _finallySourcePromise_ )
+ The job PromiseResolveThenableJob with parameters _promiseToResolve_, _thenable_, _then_, and _finallySourcePromise_ performs the following steps:
- 1. Let _resolvingFunctions_ be CreateResolvingFunctions(_promiseToResolve_).
+ 1. Let _resolvingFunctions_ be CreateResolvingFunctions(_promiseToResolve_, _finallySourcePromise_).
1. Let _thenCallResult_ be Call(_then_, _thenable_, « _resolvingFunctions_.[[Resolve]], _resolvingFunctions_.[[Reject]] »).
1. If _thenCallResult_ is an abrupt completion, then
1. Let _status_ be Call(_resolvingFunctions_.[[Reject]], *undefined*, « _thenCallResult_.[[Value]] »).
@@ -38771,7 +38783,10 @@ Promise ( _executor_ )
1. Set _promise_.[[PromiseFulfillReactions]] to a new empty List.
1. Set _promise_.[[PromiseRejectReactions]] to a new empty List.
1. Set _promise_.[[PromiseIsHandled]] to *false*.
- 1. Let _resolvingFunctions_ be CreateResolvingFunctions(_promise_).
+ 1. Let _finallySourcePromise_ be *undefined*.
+ 1. If _executor_ has a [[FinallySourcePromise]] internal slot, then
+ 1. Set _finallySourcePromise_ to _executor_.[[FinallySourcePromise]].
+ 1. Let _resolvingFunctions_ be CreateResolvingFunctions(_promise_, _finallySourcePromise_).
1. Let _completion_ be Call(_executor_, *undefined*, « _resolvingFunctions_.[[Resolve]], _resolvingFunctions_.[[Reject]] »).
1. If _completion_ is an abrupt completion, then
1. Perform ? Call(_resolvingFunctions_.[[Reject]], *undefined*, « _completion_.[[Value]] »).
@@ -39015,57 +39030,11 @@ Promise.prototype.finally ( _onFinally_ )
When the `finally` method is called with argument _onFinally_, the following steps are taken:
1. Let _promise_ be the *this* value.
- 1. If Type(_promise_) is not Object, throw a *TypeError* exception.
+ 1. If IsPromise(_promise_) is *false*, throw a *TypeError* exception.
1. Let _C_ be ? SpeciesConstructor(_promise_, %Promise%).
- 1. Assert: IsConstructor(_C_) is *true*.
- 1. If IsCallable(_onFinally_) is *false*, then
- 1. Let _thenFinally_ be _onFinally_.
- 1. Let _catchFinally_ be _onFinally_.
- 1. Else,
- 1. Let _stepsThenFinally_ be the algorithm steps defined in .
- 1. Let _thenFinally_ be CreateBuiltinFunction(_stepsThenFinally_, « [[Constructor]], [[OnFinally]] »).
- 1. Set _thenFinally_.[[Constructor]] to _C_.
- 1. Set _thenFinally_.[[OnFinally]] to _onFinally_.
- 1. Let _stepsCatchFinally_ be the algorithm steps defined in .
- 1. Let _catchFinally_ be CreateBuiltinFunction(_stepsCatchFinally_, « [[Constructor]], [[OnFinally]] »).
- 1. Set _catchFinally_.[[Constructor]] to _C_.
- 1. Set _catchFinally_.[[OnFinally]] to _onFinally_.
- 1. Return ? Invoke(_promise_, `"then"`, « _thenFinally_, _catchFinally_ »).
-
-
-
- Then Finally Functions
- A Then Finally function is an anonymous built-in function that has a [[Constructor]] and an [[OnFinally]] internal slot. The value of the [[Constructor]] internal slot is a `Promise`-like constructor function object, and the value of the [[OnFinally]] internal slot is a function object.
- When a Then Finally function _F_ is called with argument _value_, the following steps are taken:
-
- 1. Let _onFinally_ be _F_.[[OnFinally]].
- 1. Assert: IsCallable(_onFinally_) is *true*.
- 1. Let _result_ be ? Call(_onFinally_, *undefined*).
- 1. Let _C_ be _F_.[[Constructor]].
- 1. Assert: IsConstructor(_C_) is *true*.
- 1. Let _promise_ be ? PromiseResolve(_C_, _result_).
- 1. Let _valueThunk_ be equivalent to a function that returns _value_.
- 1. Return ? Invoke(_promise_, `"then"`, « _valueThunk_ »).
-
- The `length` property of a Then Finally function is *1*.
-
-
-
- Catch Finally Functions
- A Catch Finally function is an anonymous built-in function that has a [[Constructor]] and an [[OnFinally]] internal slot. The value of the [[Constructor]] internal slot is a `Promise`-like constructor function object, and the value of the [[OnFinally]] internal slot is a function object.
- When a Catch Finally function _F_ is called with argument _reason_, the following steps are taken:
-
- 1. Let _onFinally_ be _F_.[[OnFinally]].
- 1. Assert: IsCallable(_onFinally_) is *true*.
- 1. Let _result_ be ? Call(_onFinally_, *undefined*).
- 1. Let _C_ be _F_.[[Constructor]].
- 1. Assert: IsConstructor(_C_) is *true*.
- 1. Let _promise_ be ? PromiseResolve(_C_, _result_).
- 1. Let _thrower_ be equivalent to a function that throws _reason_.
- 1. Return ? Invoke(_promise_, `"then"`, « _thrower_ »).
-
- The `length` property of a Catch Finally function is *1*.
-
+ 1. Let _resultCapability_ be ? NewPromiseCapability(_C_, _promise_).
+ 1. Return PerformPromiseThen(_promise_, _onFinally_, _onFinally_, _resultCapability_).
+