Skip to content

Commit

Permalink
Normative: Improve consistency in async-related algorithms
Browse files Browse the repository at this point in the history
Used the PromiseResolve primitive instead of creating a promise
capability for the following clauses:
6.2.3.1 Await
25.1.4.2.1 %AsyncFromSyncIteratorPrototype%.next
25.1.4.2.2 %AsyncFromSyncIteratorPrototype%.return
25.1.4.2.3 %AsyncFromSyncIteratorPrototype%.throw
25.5.3.5 AsyncGeneratorResumeNext
to make them consistent with:
25.6.5.3.1 Then Finally Functions
25.6.5.3.2 Catch Finally Functions
  • Loading branch information
MayaLekova committed Jun 8, 2018
1 parent 4a0b2ad commit f363793
Showing 1 changed file with 14 additions and 19 deletions.
33 changes: 14 additions & 19 deletions spec.html
Original file line number Diff line number Diff line change
Expand Up @@ -3045,15 +3045,14 @@ <h1>Await</h1>
<p>Algorithm steps that say</p>

<emu-alg>
1. Let _completion_ be Await(_promise_).
1. Let _completion_ be Await(_value_).
</emu-alg>

<p>mean the same thing as:</p>

<emu-alg>
1. Let _asyncContext_ be the running execution context.
1. Let _promiseCapability_ be ! NewPromiseCapability(%Promise%).
1. Perform ! Call(_promiseCapability_.[[Resolve]], *undefined*, &laquo; _promise_ &raquo;).
1. Let _promise_ be ? PromiseResolve(&laquo; _value_ &raquo;).
1. Let _stepsFulfilled_ be the algorithm steps defined in <emu-xref href="#await-fulfilled" title></emu-xref>.
1. Let _onFulfilled_ be CreateBuiltinFunction(_stepsFulfilled_, &laquo; [[AsyncContext]] &raquo;).
1. Set _onFulfilled_.[[AsyncContext]] to _asyncContext_.
Expand All @@ -3062,7 +3061,7 @@ <h1>Await</h1>
1. Set _onRejected_.[[AsyncContext]] to _asyncContext_.
1. Let _throwawayCapability_ be ! NewPromiseCapability(%Promise%).
1. Set _throwawayCapability_.[[Promise]].[[PromiseIsHandled]] to *true*.
1. Perform ! PerformPromiseThen(_promiseCapability_.[[Promise]], _onFulfilled_, _onRejected_, _throwawayCapability_).
1. Perform ! PerformPromiseThen(_promise_, _onFulfilled_, _onRejected_, _throwawayCapability_).

This comment has been minimized.

Copy link
@zenparsing

zenparsing Jun 25, 2018

The only issue I can think of with this approach is that we are attaching promise value handlers on what might be a user-created promise without going through the indirection of calling "then" on that promise object.

In the following scenario:

async function f() {
  let promise = Promise.resolve(1);
  promise.then = function(...args) {
    console.log('then called');
    return Promise.prototype.then.apply(this, args);
  };
  await promise;
}

Would we expect the overridden "then" method to be called?

This comment has been minimized.

Copy link
@MayaLekova

MayaLekova Jun 26, 2018

Author Owner

I'd say no, but we don't call it with the current spec either (as far as I see from Node 8 and 10, Chrome and FF). Maybe I'm missing something from your example, because your point about calling "then" sounds correct.

1. Remove _asyncContext_ from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
1. Set the code evaluation state of _asyncContext_ such that when evaluation is resumed with a Completion _completion_, the following steps of the algorithm that invoked Await will be performed, with _completion_ available.
</emu-alg>
Expand All @@ -3073,14 +3072,14 @@ <h1>Await</h1>
<p>Await can be combined with the `?` and `!` prefixes, so that for example</p>

<emu-alg>
1. Let _value_ be ? Await(_promise_).
1. Let _result_ be ? Await(_value_).
</emu-alg>

<p>means the same thing as:</p>

<emu-alg>
1. Let _value_ be Await(_promise_).
1. ReturnIfAbrupt(_value_).
1. Let _result_ be Await(_value_).
1. ReturnIfAbrupt(_result_).
</emu-alg>
</emu-note>

Expand Down Expand Up @@ -37908,12 +37907,11 @@ <h1>%AsyncFromSyncIteratorPrototype%.next ( _value_ )</h1>
1. IfAbruptRejectPromise(_nextDone_, _promiseCapability_).
1. Let _nextValue_ be IteratorValue(_nextResult_).
1. IfAbruptRejectPromise(_nextValue_, _promiseCapability_).
1. Let _valueWrapperCapability_ be ! NewPromiseCapability(%Promise%).
1. Perform ! Call(_valueWrapperCapability_.[[Resolve]], *undefined*, &laquo; _nextValue_ &raquo;).
1. Let _valueWrapper_ be ? PromiseResolve(&laquo; _nextValue_ &raquo;).

This comment has been minimized.

Copy link
@littledan

littledan Jun 20, 2018

This is a bit of a tangent, but the repetition in the async iterator code seems to point to the need for an "AwaitIteratorResult" macro analogous to the Await macro.

This comment has been minimized.

Copy link
@MayaLekova

MayaLekova Jun 21, 2018

Author Owner

Do you find it good idea to make a part of the current change, or maybe a follow-up one?

This comment has been minimized.

Copy link
@littledan

littledan Jun 21, 2018

A separate one (maybe preceding)

1. Let _steps_ be the algorithm steps defined in <emu-xref href="#sec-async-from-sync-iterator-value-unwrap-functions" title></emu-xref>.
1. Let _onFulfilled_ be CreateBuiltinFunction(_steps_, &laquo; [[Done]] &raquo;).
1. Set _onFulfilled_.[[Done]] to _nextDone_.
1. Perform ! PerformPromiseThen(_valueWrapperCapability_.[[Promise]], _onFulfilled_, *undefined*, _promiseCapability_).
1. Perform ! PerformPromiseThen(_valueWrapper_, _onFulfilled_, *undefined*, _promiseCapability_).
1. Return _promiseCapability_.[[Promise]].
</emu-alg>
</emu-clause>
Expand Down Expand Up @@ -37944,12 +37942,11 @@ <h1>%AsyncFromSyncIteratorPrototype%.return ( _value_ )</h1>
1. IfAbruptRejectPromise(_returnDone_, _promiseCapability_).
1. Let _returnValue_ be IteratorValue(_returnResult_).
1. IfAbruptRejectPromise(_returnValue_, _promiseCapability_).
1. Let _valueWrapperCapability_ be ! NewPromiseCapability(%Promise%).
1. Perform ! Call(_valueWrapperCapability_.[[Resolve]], *undefined*, &laquo; _returnValue_ &raquo;).
1. Let _valueWrapper_ be ? PromiseResolve(&laquo; _returnValue_ &raquo;).
1. Let _steps_ be the algorithm steps defined in <emu-xref href="#sec-async-from-sync-iterator-value-unwrap-functions" title></emu-xref>.
1. Let _onFulfilled_ be CreateBuiltinFunction(_steps_, &laquo; [[Done]] &raquo;).
1. Set _onFulfilled_.[[Done]] to _returnDone_.
1. Perform ! PerformPromiseThen(_valueWrapperCapability_.[[Promise]], _onFulfilled_, *undefined*, _promiseCapability_).
1. Perform ! PerformPromiseThen(_valueWrapper_, _onFulfilled_, *undefined*, _promiseCapability_).
1. Return _promiseCapability_.[[Promise]].
</emu-alg>
</emu-clause>
Expand Down Expand Up @@ -37979,12 +37976,11 @@ <h1>%AsyncFromSyncIteratorPrototype%.throw ( _value_ )</h1>
1. IfAbruptRejectPromise(_throwDone_, _promiseCapability_).
1. Let _throwValue_ be IteratorValue(_throwResult_).
1. IfAbruptRejectPromise(_throwValue_, _promiseCapability_).
1. Let _valueWrapperCapability_ be ! NewPromiseCapability(%Promise%).
1. Perform ! Call(_valueWrapperCapability_.[[Resolve]], *undefined*, &laquo; _throwValue_ &raquo;).
1. Let _valueWrapper_ be ? PromiseResolve(&laquo; _throwValue_ &raquo;).
1. Let _steps_ be the algorithm steps defined in <emu-xref href="#sec-async-from-sync-iterator-value-unwrap-functions" title></emu-xref>.
1. Let _onFulfilled_ be CreateBuiltinFunction(_steps_, &laquo; [[Done]] &raquo;).
1. Set _onFulfilled_.[[Done]] to _throwDone_.
1. Perform ! PerformPromiseThen(_valueWrapperCapability_.[[Promise]], _onFulfilled_, *undefined*, _promiseCapability_).
1. Perform ! PerformPromiseThen(_valueWrapper_, _onFulfilled_, *undefined*, _promiseCapability_).
1. Return _promiseCapability_.[[Promise]].
</emu-alg>
</emu-clause>
Expand Down Expand Up @@ -38687,8 +38683,7 @@ <h1>AsyncGeneratorResumeNext ( _generator_ )</h1>
1. If _state_ is `"completed"`, then
1. If _completion_.[[Type]] is ~return~, then
1. Set _generator_.[[AsyncGeneratorState]] to `"awaiting-return"`.
1. Let _promiseCapability_ be ! NewPromiseCapability(%Promise%).
1. Perform ! Call(_promiseCapability_.[[Resolve]], *undefined*, &laquo; _completion_.[[Value]] &raquo;).
1. Let _promise_ be ? PromiseResolve(&laquo; _completion_.[[Value]] &raquo;).
1. Let _stepsFulfilled_ be the algorithm steps defined in <emu-xref href="#async-generator-resume-next-return-processor-fulfilled" title></emu-xref>.
1. Let _onFulfilled_ be CreateBuiltinFunction(_stepsFulfilled_, &laquo; [[Generator]] &raquo;).
1. Set _onFulfilled_.[[Generator]] to _generator_.
Expand All @@ -38697,7 +38692,7 @@ <h1>AsyncGeneratorResumeNext ( _generator_ )</h1>
1. Set _onRejected_.[[Generator]] to _generator_.
1. Let _throwawayCapability_ be ! NewPromiseCapability(%Promise%).
1. Set _throwawayCapability_.[[Promise]].[[PromiseIsHandled]] to *true*.
1. Perform ! PerformPromiseThen(_promiseCapability_.[[Promise]], _onFulfilled_, _onRejected_, _throwawayCapability_).
1. Perform ! PerformPromiseThen(_promise_, _onFulfilled_, _onRejected_, _throwawayCapability_).
1. Return *undefined*.
1. Else,
1. Assert: _completion_.[[Type]] is ~throw~.
Expand Down

0 comments on commit f363793

Please sign in to comment.