Async Iteration (original) (raw)
Stage 3 Draft / February 12, 2018
1Introduction
This proposal adds syntactic support for asynchronous iteration using the AsyncIterable and AsyncIterator protocols. It introduces a new IterationStatement, for
-await
-of
, and adds syntax for creating async generator functions and methods.
See the proposal repository for background material and discussion.
Note
This proposal depends upon the async functions proposal.
2Well-Known Symbols
Editor's Note
The spec's existing Table 1 in 6.1.5.1 should be expanded with the following rows:
Table 1: Well-known Symbols
Specification Name | [[Description]] | Value and Purpose |
---|---|---|
@@asyncIterator | "Symbol.asyncIterator" | A method that returns the default AsyncIterator for an object. Called by the semantics of the for-await-of statement. |
3Well-Known Intrinsic Objects
Editor's Note
The spec's existing Table 7 in 6.1.7.4 should be expanded with the following rows:
Table 2: Well-known Intrinsic Objects
Intrinsic Name | Global Name | ECMAScript Language Association |
---|---|---|
%AsyncGenerator% | The initial value of the prototype property of %AsyncGeneratorFunction% | |
%AsyncGeneratorFunction% | The constructor of async iterator objects (11.3.1) | |
%AsyncGeneratorPrototype% | The initial value of the prototype property of %AsyncGenerator% | |
%AsyncIteratorPrototype% | An object that all standard built-in async iterator objects indirectly inherit from | |
%AsyncFromSyncIteratorPrototype% | The prototype of async-from-sync iterator objects (11.1.3) |
4The Completion Record Specification Type
Editor's Note
This patch adds clauses to
.
4.1Await
Editor's Note
The AsyncFunctionAwait abstract operation could probably be refactored in terms of this primitive.
Algorithm steps that say
- Let completion be Await(promise).
mean the same thing as:
- Let asyncContext be the running execution context.
- Let promiseCapability be ! NewPromiseCapability(%Promise%).
- Perform ! Call(promiseCapability.[[Resolve]], undefined, « promise »).
- Let onFulfilled be a new built-in function object as defined in Await Fulfilled Functions.
- Let onRejected be a new built-in function object as defined in Await Rejected Functions.
- Set onFulfilled and onRejected's [[AsyncContext]] internal slots to asyncContext.
- Let throwawayCapability be NewPromiseCapability(%Promise%).
- Set throwawayCapability.[[Promise]].[[PromiseIsHandled]] to true.
- Perform ! PerformPromiseThen(promiseCapability.[[Promise]], onFulfilled, onRejected, throwawayCapability).
- 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.
- 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.
where all variables in the above steps, with the exception of completion, are ephemeral and visible only in the steps pertaining to Await.
Note
Await can be combined with the ?
and !
prefixes, so that for example
- Let value be ? Await(promise).
means the same thing as:
- Let value be Await(promise).
- ReturnIfAbrupt(value).
4.1.1Await Fulfilled Functions
An Await fulfilled function is an anonymous built-in function that is used as part of the Await specification device to deliver the promise fulfillment value to the caller as a normal completion. Each Await fulfilled function has an [[AsyncContext]] internal slot.
When an Await fulfilled function F is called with argument value, the following steps are taken:
- Let asyncContext be F.[[AsyncContext]].
- Let prevContext be the running execution context.
- Suspend prevContext.
- Push asyncContext onto the execution context stack; asyncContext is now the running execution context.
- Resume the suspended evaluation of asyncContext using NormalCompletion(value) as the result of the operation that suspended it.
- Assert: When we reach this step, asyncContext has already been removed from the execution context stack and prevContext is the currently running execution context.
- Return undefined.
The length
property of an Await fulfilled function is 1.
4.1.2Await Rejected Functions
An Await rejected function is an anonymous built-in function that is used as part of the Await specification device to deliver the promise rejection reason to the caller as an abrupt throw completion. Each Await rejected function has an [[AsyncContext]] internal slot.
When an Await rejected function F is called with argument reason, the following steps are taken:
- Let asyncContext be F.[[AsyncContext]].
- Let prevContext be the running execution context.
- Suspend prevContext.
- Push asyncContext onto the execution context stack; asyncContext is now the running execution context.
- Resume the suspended evaluation of asyncContext using Completion{[[Type]]: throw, [[Value]]: reason, [[Target]]: empty} as the result of the operation that suspended it.
- Assert: When we reach this step, asyncContext has already been removed from the execution context stack and prevContext is the currently running execution context.
- Return undefined.
The length
property of an Await rejected function is 1.
5Operations on Iterator Objects
Editor's Note
These patches modify clauses of and add clauses to
.
5.1GetIterator ( obj [ , hint ][ , method ] )
Editor's Note
This abstract operation has been modified to accept an optional parameter hint which indicates whether we should attempt to find an async iterator for the object. Existing call sites which use the optional method parameter (Array.from
and IterableToArrayLike) must be updated to pass the normal hint.
The abstract operation GetIterator with argument obj and optional arguments hint and method performs the following steps:
- If hint was not passed, let hint be normal.
- If method is not present, then
Set method to ? GetMethod(obj, @@iterator).- If hint is async,
- Set method to ? GetMethod(obj, @@asyncIterator).
- If method is undefined,
1. Let syncMethod be ? GetMethod(obj, @@iterator).
2. Let syncIteratorRecord be ? GetIterator(obj, normal, syncMethod).
3. Return ? CreateAsyncFromSyncIterator(syncIteratorRecord).
- Otherwise, set method to ? GetMethod(obj, @@iterator).
- Let iterator be ? Call(method, obj).
- If Type(iterator) is not Object, throw a TypeError exception.
- Let nextMethod be ? GetV(iterator,
"next"
). - Let iteratorRecord be Record {[[Iterator]]: iterator, [[NextMethod]]: nextMethod, [[Done]]: false}.
- Return iteratorRecord.
5.2AsyncIteratorClose ( iteratorRecord, completion )
The abstract operation AsyncIteratorClose with arguments iteratorRecord and completion is used to notify an async iterator that it should perform any actions it would normally perform when it has reached its completed state:
- Assert: Type(iteratorRecord.[[Iterator]]) is Object.
- Assert: completion is a Completion Record.
- Let iterator be iteratorRecord.[[Iterator]].
- Let return be ? GetMethod(iterator,
"return"
). - If return is undefined, return Completion(completion).
- Let innerResult be Call(return, iterator, « »).
- If innerResult.[[Type]] is normal, set innerResult to Await(innerResult.[[Value]]).
- If completion.[[Type]] is throw, return Completion(completion).
- If innerResult.[[Type]] is throw, return Completion(innerResult).
- If Type(innerResult.[[Value]]) is not Object, throw a TypeError exception.
- Return Completion(completion).
6ECMAScript Function Objects
Editor's Note
This patch adds a clause to
.
6.1AsyncGeneratorFunctionCreate (kind, ParameterList, Body, Scope, Strict)
The abstract operation AsyncGeneratorFunctionCreate requires the arguments: kind which is one of (Normal, Method), a parameter list production specified by ParameterList, a body production specified by Body, a Lexical Environment specified by Scope, and a Boolean flag Strict. AsyncGeneratorFunctionCreate performs the following steps:
- Let functionPrototype be the intrinsic object %AsyncGenerator%.
- Let F be ! FunctionAllocate(functionPrototype, Strict,
"generator"
). - Return ! FunctionInitialize(F, kind, ParameterList, Body, Scope).
7ECMAScript Language: Statements and Declarations
Editor's Note
These patches modify clauses of and add clauses to
.
7.1The return
Statement
Syntax
ReturnStatement[Yield, Await]:return; return[no LineTerminator here]Expression[+In, ?Yield, ?Await]; Note
A return
statement causes a function to cease execution and return a value to the caller. If Expression is omitted, the return value is undefined. Otherwise, the return value is the value of Expression.
7.1.1Runtime Semantics: Evaluation
ReturnStatement:return;
- Return Completion{[[Type]]: return, [[Value]]: undefined, [[Target]]: empty}. ReturnStatement:returnExpression;
- Let exprRef be the result of evaluating Expression.
- Let exprValue be ? GetValue(exprRef).
- If ! GetGeneratorKind() is async, set exprValue to ? Await(exprValue).
- Return Completion{[[Type]]: return, [[Value]]: exprValue, [[Target]]: empty}.
7.2Iteration Statements
Syntax
IterationStatement[Yield, Await, Return]:doStatement[?Yield, ?Await, ?Return]while(Expression[+In, ?Yield, ?Await]); while(Expression[+In, ?Yield, ?Await])Statement[?Yield, ?Await, ?Return] for([lookahead ∉ { let [ }]Expression[~In, ?Yield, ?Await]opt;Expression[+In, ?Yield, ?Await]opt;Expression[+In, ?Yield, ?Await]opt)Statement[?Yield, ?Await, ?Return] for(varVariableDeclarationList[~In, ?Yield, ?Await];Expression[+In, ?Yield, ?Await]opt;Expression[+In, ?Yield, ?Await]opt)Statement[?Yield, ?Await, ?Return] for(LexicalDeclaration[~In, ?Yield, ?Await]Expression[+In, ?Yield, ?Await]opt;Expression[+In, ?Yield, ?Await]opt)Statement[?Yield, ?Await, ?Return] for([lookahead ∉ { let [ }]LeftHandSideExpression[?Yield, ?Await]inExpression[+In, ?Yield, ?Await])Statement[?Yield, ?Await, ?Return] for(varForBinding[?Yield, ?Await]inExpression[+In, ?Yield, ?Await])Statement[?Yield, ?Await, ?Return] for(ForDeclaration[?Yield, ?Await]inExpression[+In, ?Yield, ?Await])Statement[?Yield, ?Await, ?Return] for([lookahead ≠ let]LeftHandSideExpression[?Yield, ?Await]ofAssignmentExpression[+In, ?Yield, ?Await])Statement[?Yield, ?Await, ?Return] for(varForBinding[?Yield, ?Await]ofAssignmentExpression[+In, ?Yield, ?Await])Statement[?Yield, ?Await, ?Return] for(ForDeclaration[?Yield, ?Await]ofAssignmentExpression[+In, ?Yield, ?Await])Statement[?Yield, ?Await, ?Return] [+Await]forawait([lookahead ≠ let]LeftHandSideExpression[?Yield, ?Await]ofAssignmentExpression[+In, ?Yield, ?Await])Statement[?Yield, ?Await, ?Return] [+Await]forawait(varForBinding[?Yield, ?Await]ofAssignmentExpression[+In, ?Yield, ?Await])Statement[?Yield, ?Await, ?Return] [+Await]forawait(ForDeclaration[?Yield, ?Await]ofAssignmentExpression[+In, ?Yield, ?Await])Statement[?Yield, ?Await, ?Return] ForDeclaration[Yield, Await]:LetOrConstForBinding[?Yield, ?Await] ForBinding[Yield, Await]:BindingIdentifier[?Yield, ?Await] BindingPattern[?Yield, ?Await] Note
This section is extended by Annex B.3.6.
7.2.1Semantics
7.2.1.1Static Semantics: Early Errors
IterationStatement:doStatementwhile(Expression); while(Expression)Statement for(Expressionopt;Expressionopt;Expressionopt)Statement for(varVariableDeclarationList;Expressionopt;Expressionopt)Statement for(LexicalDeclarationExpressionopt;Expressionopt)Statement for(LeftHandSideExpressioninExpression)Statement for(varForBindinginExpression)Statement for(ForDeclarationinExpression)Statement for(LeftHandSideExpressionofAssignmentExpression)Statement for(varForBindingofAssignmentExpression)Statement for(ForDeclarationofAssignmentExpression)Statement forawait(LeftHandSideExpressionofAssignmentExpression)Statement forawait(varForBindingofAssignmentExpression)Statement forawait(ForDeclarationofAssignmentExpression)Statement
- It is a Syntax Error if IsLabelledFunction(Statement) is true. Note
It is only necessary to apply this rule if the extension specified in B.3.2 is implemented.
7.2.2The for
-in
and, for
-of
, and for
-await
-of
Statements
7.2.2.1Static Semantics: Early Errors
IterationStatement:for(LeftHandSideExpressioninExpression)Statement for(LeftHandSideExpressionofAssignmentExpression)Statement forawait(LeftHandSideExpressionofAssignmentExpression)Statement
- It is a Syntax Error if LeftHandSideExpression is either an ObjectLiteral or an ArrayLiteral and if the lexical token sequence matched by LeftHandSideExpression cannot be parsed with no tokens left over using AssignmentPattern as the goal symbol.
If LeftHandSideExpression is either an ObjectLiteral or an ArrayLiteral and if the lexical token sequence matched by LeftHandSideExpression can be parsed with no tokens left over using AssignmentPattern as the goal symbol then the following rules are not applied. Instead, the Early Error rules for AssignmentPattern are used.
- It is a Syntax Error if IsValidSimpleAssignmentTarget of LeftHandSideExpression is false.
- It is a Syntax Error if the LeftHandSideExpression is CoverParenthesizedExpressionAndArrowParameterList:(Expression) and Expression derives a production that would produce a Syntax Error according to these rules if that production is substituted for LeftHandSideExpression. This rule is recursively applied. Note
The last rule means that the other rules are applied even if parentheses surround Expression.
IterationStatement:for(ForDeclarationinExpression)Statement for(ForDeclarationofAssignmentExpression)Statement forawait(ForDeclarationofAssignmentExpression)Statement
- It is a Syntax Error if the BoundNames of ForDeclaration contains
"let"
. - It is a Syntax Error if any element of the BoundNames of ForDeclaration also occurs in the VarDeclaredNames of Statement.
- It is a Syntax Error if the BoundNames of ForDeclaration contains any duplicate entries.
7.2.2.2Static Semantics: ContainsDuplicateLabels
With argument labelSet.
IterationStatement:for(LeftHandSideExpressioninExpression)Statement for(varForBindinginExpression)Statement for(ForDeclarationinExpression)Statement for(LeftHandSideExpressionofAssignmentExpression)Statement for(varForBindingofAssignmentExpression)Statement for(ForDeclarationofAssignmentExpression)Statement forawait(LeftHandSideExpressionofAssignmentExpression)Statement forawait(varForBindingofAssignmentExpression)Statement forawait(ForDeclarationofAssignmentExpression)Statement
- Return ContainsDuplicateLabels of Statement with argument labelSet. Note
This section is extended by Annex B.3.6.
7.2.2.3Static Semantics: ContainsUndefinedBreakTarget
With argument labelSet.
IterationStatement:for(LeftHandSideExpressioninExpression)Statement for(varForBindinginExpression)Statement for(ForDeclarationinExpression)Statement for(LeftHandSideExpressionofAssignmentExpression)Statement for(varForBindingofAssignmentExpression)Statement for(ForDeclarationofAssignmentExpression)Statement forawait(LeftHandSideExpressionofAssignmentExpression)Statement forawait(varForBindingofAssignmentExpression)Statement forawait(ForDeclarationofAssignmentExpression)Statement
- Return ContainsUndefinedBreakTarget of Statement with argument labelSet. Note
This section is extended by Annex B.3.6.
7.2.2.4Static Semantics: ContainsUndefinedContinueTarget
With arguments iterationSet and labelSet.
IterationStatement:for(LeftHandSideExpressioninExpression)Statement for(varForBindinginExpression)Statement for(ForDeclarationinExpression)Statement for(LeftHandSideExpressionofAssignmentExpression)Statement for(varForBindingofAssignmentExpression)Statement for(ForDeclarationofAssignmentExpression)Statement forawait(LeftHandSideExpressionofAssignmentExpression)Statement forawait(varForBindingofAssignmentExpression)Statement forawait(ForDeclarationofAssignmentExpression)Statement
- Return ContainsUndefinedContinueTarget of Statement with arguments iterationSet and « ». Note
This section is extended by Annex B.3.6.
7.2.2.5Static Semantics: VarDeclaredNames
IterationStatement:for(LeftHandSideExpressioninExpression)Statement
- Return the VarDeclaredNames of Statement. IterationStatement:for(varForBindinginExpression)Statement
- Let names be the BoundNames of ForBinding.
- Append to names the elements of the VarDeclaredNames of Statement.
- Return names. IterationStatement:for(ForDeclarationinExpression)Statement
- Return the VarDeclaredNames of Statement. IterationStatement:for(LeftHandSideExpressionofAssignmentExpression)Statement forawait(LeftHandSideExpressionofAssignmentExpression)Statement
- Return the VarDeclaredNames of Statement. IterationStatement:for(varForBindingofAssignmentExpression)Statement forawait(varForBindingofAssignmentExpression)Statement
- Let names be the BoundNames of ForBinding.
- Append to names the elements of the VarDeclaredNames of Statement.
- Return names. IterationStatement:for(ForDeclarationofAssignmentExpression)Statement forawait(ForDeclarationofAssignmentExpression)Statement
- Return the VarDeclaredNames of Statement. Note
This section is extended by Annex B.3.6.
7.2.2.6Static Semantics: VarScopedDeclarations
IterationStatement:for(LeftHandSideExpressioninExpression)Statement
- Return the VarScopedDeclarations of Statement. IterationStatement:for(varForBindinginExpression)Statement
- Let declarations be a List containing ForBinding.
- Append to declarations the elements of the VarScopedDeclarations of Statement.
- Return declarations. IterationStatement:for(ForDeclarationinExpression)Statement
- Return the VarScopedDeclarations of Statement. IterationStatement:for(LeftHandSideExpressionofAssignmentExpression)Statement forawait(LeftHandSideExpressionofAssignmentExpression)Statement
- Return the VarScopedDeclarations of Statement. IterationStatement:for(varForBindingofAssignmentExpression)Statement forawait(varForBindingofAssignmentExpression)Statement
- Let declarations be a List containing ForBinding.
- Append to declarations the elements of the VarScopedDeclarations of Statement.
- Return declarations. IterationStatement:for(ForDeclarationofAssignmentExpression)Statement forawait(ForDeclarationofAssignmentExpression)Statement
- Return the VarScopedDeclarations of Statement. Note
This section is extended by Annex B.3.6.
7.2.2.7Runtime Semantics: LabelledEvaluation
With argument labelSet.
IterationStatement:for(LeftHandSideExpressioninExpression)Statement
- Let keyResult be ? ForIn/OfHeadEvaluation(« », Expression, enumerate).
- Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, assignment, labelSet). IterationStatement:for(varForBindinginExpression)Statement
- Let keyResult be ? ForIn/OfHeadEvaluation(« », Expression, enumerate).
- Return ? ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, varBinding, labelSet). IterationStatement:for(ForDeclarationinExpression)Statement
- Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, Expression, enumerate).
- Return ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, lexicalBinding, labelSet). IterationStatement:for(LeftHandSideExpressionofAssignmentExpression)Statement
- Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« », AssignmentExpression, iterate).
- Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, assignment, labelSet). IterationStatement:for(varForBindingofAssignmentExpression)Statement
- Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« », AssignmentExpression, iterate).
- Return ? ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, varBinding, labelSet). IterationStatement:for(ForDeclarationofAssignmentExpression)Statement
- Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, AssignmentExpression, iterate).
- Return ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, lexicalBinding, labelSet). IterationStatement:forawait(LeftHandSideExpressionofAssignmentExpression)Statement
- Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« », AssignmentExpression, async-iterate).
- Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, assignment, labelSet, async). IterationStatement:forawait(varForBindingofAssignmentExpression)Statement
- Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« », AssignmentExpression, async-iterate).
- Return ? ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, varBinding, labelSet, async). IterationStatement:forawait(ForDeclarationofAssignmentExpression)Statement
- Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, AssignmentExpression, async-iterate).
- Return ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, lexicalBinding, labelSet, async). Note
This section is extended by Annex B.3.6.
7.2.2.8Runtime Semantics: ForIn/OfHeadEvaluation ( TDZnames, expr, iterationKind )
The abstract operation ForIn/OfHeadEvaluation is called with arguments TDZnames, expr, and iterationKind. The value of iterationKind is either enumerate or, iterate, or async-iterate.
- Let oldEnv be the running execution context's LexicalEnvironment.
- If TDZnames is not an empty List, then
- Assert: TDZnames has no duplicate entries.
- Let TDZ be ! NewDeclarativeEnvironment(oldEnv).
- Let TDZEnvRec be TDZ's EnvironmentRecord.
- For each string name in TDZnames, do
- Perform ! TDZEnvRec.CreateMutableBinding(name, false).
- Set the running execution context's LexicalEnvironment to TDZ.
- Let exprRef be the result of evaluating the production that is expr.
- Set the running execution context's LexicalEnvironment to oldEnv.
- Let exprValue be ? GetValue(exprRef).
- If iterationKind is enumerate, then
- If exprValue.[[Value]] is null or undefined, then
- Return Completion{[[Type]]: break, [[Value]]: empty, [[Target]]: empty}.
- Let obj be ? ToObject(exprValue).
- Return ? obj.[[Enumerate]]().
- If exprValue.[[Value]] is null or undefined, then
- Else,
- If iterationKind is async-iterate, let iteratorHint be async.
- Else, let iteratorHint be normal.
- Return ? GetIterator(exprValue, iteratorHint).
7.2.2.9Runtime Semantics: ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, lhsKind, labelSet [ , iteratorKind ] )
The abstract operation ForIn/OfBodyEvaluation is called with arguments lhs, stmt, iteratorRecord, lhsKind, and labelSet, and optional argument iteratorKind. The value of lhsKind is either assignment, varBinding or lexicalBinding. The value of iteratorKind is either normal or async.
- If iteratorKind was not passed, let iteratorKind be normal.
- Let oldEnv be the running execution context's LexicalEnvironment.
- Let V be undefined.
- Let destructuring be IsDestructuring of lhs.
- If destructuring is true and if lhsKind is assignment, then
- Assert: lhs is a LeftHandSideExpression.
- Let assignmentPattern be the parse of the source text corresponding to lhs using AssignmentPattern as the goal symbol.
- Repeat
Let nextResult be ? IteratorStep(iteratorRecord).If nextResult is false, return NormalCompletion(V).- Let nextResult be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]], « »).
- If iteratorKind is async, then set nextResult to ? Await(nextResult).
- If Type(nextResult) is not Object, throw a TypeError exception.
- Let done be ? IteratorComplete(nextResult).
- If done is true, return NormalCompletion(V).
- Let nextValue be ? IteratorValue(nextResult).
- If lhsKind is either assignment or varBinding, then
- If destructuring is false, then
1. Let lhsRef be the result of evaluating lhs (it may be evaluated repeatedly).
- If destructuring is false, then
- Else,
- Assert: lhsKind is lexicalBinding.
- Assert: lhs is a ForDeclaration.
- Let iterationEnv be NewDeclarativeEnvironment(oldEnv).
- Perform BindingInstantiation for lhs passing iterationEnv as the argument.
- Set the running execution context's LexicalEnvironment to iterationEnv.
- If destructuring is false, then
1. Assert: lhs binds a single name.
2. Let lhsName be the sole element of BoundNames of lhs.
3. Let lhsRef be ResolveBinding(lhsName).
4. Assert: lhsRef is not an abrupt completion.
- If destructuring is false, then
- If lhsRef is an abrupt completion, then
1. Let status be lhsRef. - Else if lhsKind is lexicalBinding, then
1. Let status be InitializeReferencedBinding(lhsRef, nextValue). - Else,
1. Let status be PutValue(lhsRef, nextValue).
- If lhsRef is an abrupt completion, then
- Else,
- If lhsKind is assignment, then
1. Let status be the result of performing DestructuringAssignmentEvaluation of assignmentPattern using nextValue as the argument. - Else if lhsKind is varBinding, then
1. Assert: lhs is a ForBinding.
2. Let status be the result of performing BindingInitialization for lhs passing nextValue and undefined as the arguments. - Else,
1. Assert: lhsKind is lexicalBinding.
2. Assert: lhs is a ForDeclaration.
3. Let status be the result of performing BindingInitialization for lhs passing nextValue and iterationEnv as arguments.
- If lhsKind is assignment, then
- If status is an abrupt completion, then
- Set the running execution context's LexicalEnvironment to oldEnv.
- If iteratorKind is async, return ? AsyncIteratorClose(iteratorRecord, status).
- Return ? IteratorClose(iteratorRecord, status).
- Let result be the result of evaluating stmt.
- Set the running execution context's LexicalEnvironment to oldEnv.
- If ! LoopContinues(result, labelSet) is false,
return ? IteratorClose(iteratorRecord, UpdateEmpty(result, V))then- Let status be UpdateEmpty(result, V).
- If iteratorKind is async, return ? AsyncIteratorClose(iteratorRecord, status).
- Return ? IteratorClose(iteratorRecord, status).
- If result.[[Value]] is not empty, let V be result.[[Value]].
8ECMAScript Language: Functions and Classes
Editor's Note
These patches modify clauses of and add clauses to
.
8.1Method Definitions
8.1.1Static Semantics: SpecialMethod
MethodDefinition:PropertyName(UniqueFormalParameters){FunctionBody}
- Return false. MethodDefinition:GeneratorMethod AsyncGeneratorMethod getPropertyName(){FunctionBody} setPropertyName(PropertySetParameterList){FunctionBody}
- Return true.
8.2Generator Definitions
8.2.1Runtime Semantics: Evaluation
YieldExpression:yield
- Let generatorKind be ! GetGeneratorKind().
- If generatorKind is async, then return ? AsyncGeneratorYield(undefined).
- Otherwise, r
Return ? GeneratorYield(CreateIterResultObject(undefined, false)). YieldExpression:yieldAssignmentExpression - Let generatorKind be ! GetGeneratorKind().
- Let exprRef be the result of evaluating AssignmentExpression.
- Let value be ? GetValue(exprRef).
- If generatorKind is async, then return ? AsyncGeneratorYield(value).
- Otherwise, r
Return ? GeneratorYield(CreateIterResultObject(value, false)). YieldExpression:yield*AssignmentExpression - Let generatorKind be ! GetGeneratorKind().
- Let exprRef be the result of evaluating AssignmentExpression.
- Let value be ? GetValue(exprRef).
- Let iteratorRecord be ? GetIterator(value, generatorKind).
- Let iterator be iteratorRecord.[[Iterator]].
- Let received be NormalCompletion(undefined).
- Repeat
- If received.[[Type]] is normal, then
Let innerResult be ? IteratorNext(iteratorRecord, received.[[Value]]).- Let innerResult be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]], « received.[[Value]] »).
- If generatorKind is async, then set innerResult to ? Await(innerResult).
- If Type(innerResult) is not Object, throw a TypeError exception.
- Let done be ? IteratorComplete(innerResult).
- If done is true, then
1. Return ? IteratorValue(innerResult). - If generatorKind is async, then let received be AsyncGeneratorYield(? IteratorValue(innerResult)).
- Else, l
Let received be GeneratorYield(innerResult).
- Else if received.[[Type]] is throw, then
- Let throw be ? GetMethod(iterator,
"throw"
). - If throw is not undefined, then
1. Let innerResult be ? Call(throw, iterator, « received.[[Value]] »).
2. If generatorKind is async, then set innerResult to ? Await(innerResult).
3. NOTE: Exceptions from the inner iteratorthrow
method are propagated. Normal completions from an innerthrow
method are processed similarly to an innernext
.
4. If Type(innerResult) is not Object, throw a TypeError exception.
5. Let done be ? IteratorComplete(innerResult).
6. If done is true, then
1. Return ? IteratorValue(innerResult).
7. If generatorKind is async, then let received be AsyncGeneratorYield(? IteratorValue(innerResult)).
8. Else, lLet received be GeneratorYield(innerResult). - Else,
1. NOTE: If iterator does not have athrow
method, this throw is going to terminate theyield*
loop. But first we need to give iterator a chance to clean up.
2. Let closeCompletion be Completion{[[Type]]: normal, [[Value]]: empty, [[Target]]: empty}.
3. If generatorKind is async, perform ? AsyncIteratorClose(iteratorRecord, closeCompletion).
4. Else, pPerform ? IteratorClose(iteratorRecord,Completion{[[Type]]: normal, [[Value]]: empty, [[Target]]: empty}closeCompletion).
5. NOTE: The next step throws a TypeError to indicate that there was ayield*
protocol violation: iterator does not have athrow
method.
6. Throw a TypeError exception.
- Let throw be ? GetMethod(iterator,
- Else,
- Assert: received.[[Type]] is return.
- Let return be ? GetMethod(iterator,
"return"
). - If return is undefined,
return Completion(received).then:
1. If generatorKind is async, then set received.[[Value]] to ? Await(received.[[Value]]).
2. Return Completion(received). - Let innerReturnResult be ? Call(return, iterator, « received.[[Value]] »).
- If generatorKind is async, then set innerReturnResult to ? Await(innerReturnResult).
- If Type(innerReturnResult) is not Object, throw a TypeError exception.
- Let done be ? IteratorComplete(innerReturnResult).
- If done is true, then
1. Let value be ? IteratorValue(innerReturnResult).
2. Return Completion{[[Type]]: return, [[Value]]: value, [[Target]]: empty}. - If generatorKind is async, then let received be AsyncGeneratorYield(? IteratorValue(innerResult)).
- Else, l
Let received be GeneratorYield(innerResult).
- If received.[[Type]] is normal, then
8.3Async Generator Function Definitions
Syntax
AsyncGeneratorMethod[Yield, Await]:async[no LineTerminator here]*PropertyName[?Yield, ?Await](UniqueFormalParameters[+Yield, +Await]){AsyncGeneratorBody} AsyncGeneratorDeclaration[Yield, Await, Default]:async[no LineTerminator here]function*BindingIdentifier[?Yield, ?Await](FormalParameters[+Yield, +Await]){AsyncGeneratorBody} [+Default]async[no LineTerminator here]function*(FormalParameters[+Yield, +Await]){AsyncGeneratorBody} AsyncGeneratorExpression:async[no LineTerminator here]function*BindingIdentifier[+Yield, +Await]opt(FormalParameters[+Yield, +Await]){AsyncGeneratorBody} AsyncGeneratorBody:FunctionBody[+Yield, +Await] Note 1
YieldExpression and AwaitExpression cannot be used within the FormalParameters of an async generator function because any expressions that are part of FormalParameters are evaluated before the resulting async generator object is in a resumable state.
Note 2
Abstract operations relating to async generator objects are defined in 11.4.3.
8.3.1Static Semantics: Early Errors
AsyncGeneratorMethod:*PropertyName(UniqueFormalParameters){AsyncGeneratorBody}
- It is a Syntax Error if HasDirectSuper of AsyncGeneratorMethod is true.
- It is a Syntax Error if UniqueFormalParameters Contains YieldExpression is true.
- It is a Syntax Error if UniqueFormalParameters Contains AwaitExpression is true.
- It is a Syntax Error if ContainsUseStrict of AsyncGeneratorBody is true and IsSimpleParameterList of UniqueFormalParameters is false.
- It is a Syntax Error if any element of the BoundNames of UniqueFormalParameters also occurs in the LexicallyDeclaredNames of AsyncGeneratorBody. AsyncGeneratorDeclaration:function*BindingIdentifier(FormalParameters){AsyncGeneratorBody} AsyncGeneratorDeclaration:function*(FormalParameters){AsyncGeneratorBody} AsyncGeneratorDeclaration:function*BindingIdentifieropt(FormalParameters){AsyncGeneratorBody}
- If the source code matching this production is strict mode code, the Early Error rules for UniqueFormalParameters:FormalParameters are applied.
- If the source code matching this production is strict mode code, it is a Syntax Error if BindingIdentifier is the IdentifierName
eval
or the IdentifierNamearguments
. - It is a Syntax Error if ContainsUseStrict of AsyncGeneratorBody is true and IsSimpleParameterList of FormalParameters is false.
- It is a Syntax Error if any element of the BoundNames of FormalParameters also occurs in the LexicallyDeclaredNames of AsyncGeneratorBody.
- It is a Syntax Error if FormalParameters Contains YieldExpression is true.
- It is a Syntax Error if FormalParameters Contains AwaitExpression is true.
- It is a Syntax Error if FormalParameters Contains SuperProperty is true.
- It is a Syntax Error if AsyncGeneratorBody Contains SuperProperty is true.
- It is a Syntax Error if FormalParameters Contains SuperCall is true.
- It is a Syntax Error if AsyncGeneratorBody Contains SuperCall is true.
8.3.2Static Semantics: BoundNames
AsyncGeneratorDeclaration:function*BindingIdentifier(FormalParameters){AsyncGeneratorBody}
- Return the BoundNames of BindingIdentifier. AsyncGeneratorDeclaration:function*(FormalParameters){AsyncGeneratorBody}
- Return «
"*default*"
». Note
"*default*"
is used within this specification as a synthetic name for hoistable anonymous functions that are defined using export declarations.
8.3.3Static Semantics: ComputedPropertyContains
With parameter symbol.
AsyncGeneratorMethod:*PropertyName(UniqueFormalParameters){AsyncGeneratorBody}
- Return the result of ComputedPropertyContains for PropertyName with argument symbol.
8.3.4Static Semantics: Contains
With parameter symbol.
AsyncGeneratorDeclaration:function*BindingIdentifier(FormalParameters){AsyncGeneratorBody} AsyncGeneratorDeclaration:function*(FormalParameters){AsyncGeneratorBody} AsyncGeneratorExpression:function*BindingIdentifieropt(FormalParameters){AsyncGeneratorBody}
- Return false. Note
Static semantic rules that depend upon substructure generally do not look into function definitions.
8.3.5Static Semantics: HasDirectSuper
AsyncGeneratorMethod:*PropertyName(UniqueFormalParameters){AsyncGeneratorBody}
- If UniqueFormalParameters Contains SuperCall is true, return true.
- Return AsyncGeneratorBody Contains SuperCall.
8.3.6Static Semantics: HasName
AsyncGeneratorExpression:function*(FormalParameters){AsyncGeneratorBody}
- Return false. AsyncGeneratorExpression:function*BindingIdentifier(FormalParameters){AsyncGeneratorBody}
- Return true.
8.3.7Static Semantics: IsConstantDeclaration
AsyncGeneratorDeclaration:function*BindingIdentifier(FormalParameters){AsyncGeneratorBody} AsyncGeneratorDeclaration:function*(FormalParameters){AsyncGeneratorBody}
- Return false.
8.3.8Static Semantics: IsFunctionDefinition
AsyncGeneratorExpression:function*BindingIdentifieropt(FormalParameters){AsyncGeneratorBody}
- Return true.
8.3.9Static Semantics: PropName
AsyncGeneratorMethod:*PropertyName(UniqueFormalParameters){AsyncGeneratorBody}
- Return PropName of PropertyName.
8.3.10Runtime Semantics: EvaluateBody
With parameters functionObject and List argumentsList.
AsyncGeneratorBody:FunctionBody
- Perform ? FunctionDeclarationInstantiation(functionObject, argumentsList).
- Let generator be ? OrdinaryCreateFromConstructor(functionObject,
"%AsyncGeneratorPrototype%"
, « [[AsyncGeneratorState]], [[AsyncGeneratorContext]], [[AsyncGeneratorQueue]] »). - Perform ! AsyncGeneratorStart(generator, FunctionBody).
- Return Completion{[[Type]]: return, [[Value]]: generator, [[Target]]: empty}.
8.3.11Runtime Semantics: InstantiateFunctionObject
With parameter scope.
AsyncGeneratorDeclaration:async[no LineTerminator here]function*BindingIdentifier(FormalParameters){AsyncGeneratorBody}
- If the function code for AsyncGeneratorDeclaration is strict mode code, let strict be true. Otherwise let strict be false.
- Let name be StringValue of BindingIdentifier.
- Let F be ! AsyncGeneratorFunctionCreate(Normal, FormalParameters, AsyncGeneratorBody, scope, strict).
- Let prototype be ! ObjectCreate(%AsyncGeneratorPrototype%).
- Perform ! DefinePropertyOrThrow(F,
"prototype"
, PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}). - Perform ! SetFunctionName(F, name).
- Return F. AsyncGeneratorDeclaration:async[no LineTerminator here]function*(FormalParameters){AsyncGeneratorBody}
- If the function code for AsyncGeneratorDeclaration is strict mode code, let strict be true. Otherwise let strict be false.
- Let F be AsyncGeneratorFunctionCreate(Normal, FormalParameters, AsyncGeneratorBody, scope, strict).
- Let prototype be ObjectCreate(%AsyncGeneratorPrototype%).
- Perform DefinePropertyOrThrow(F,
"prototype"
, PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}). - Perform SetFunctionName(F,
"default"
). - Return F. Note
An anonymous AsyncGeneratorDeclaration can only occur as part of an export default
declaration.
8.3.12Runtime Semantics: PropertyDefinitionEvaluation
With parameter object and enumerable.
AsyncGeneratorMethod:async[no LineTerminator here]*PropertyName(UniqueFormalParameters){AsyncGeneratorBody}
- Let propKey be the result of evaluating PropertyName.
- ReturnIfAbrupt(propKey).
- If the function code for this AsyncGeneratorMethod is strict mode code, let strict be true. Otherwise let strict be false.
- Let scope be the running execution context's LexicalEnvironment.
- Let closure be ! AsyncGeneratorFunctionCreate(Method, UniqueFormalParameters, AsyncGeneratorBody, scope, strict).
- Perform ! MakeMethod(closure, object).
- Let prototype be ! ObjectCreate(%AsyncGeneratorPrototype%).
- Perform ! DefinePropertyOrThrow(closure,
"prototype"
, PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}). - Perform ! SetFunctionName(closure, propKey).
- Let desc be PropertyDescriptor{[[Value]]: closure, [[Writable]]: true, [[Enumerable]]: enumerable, [[Configurable]]: true}.
- Return ? DefinePropertyOrThrow(object, propKey, desc).
8.3.13Runtime Semantics: Evaluation
AsyncGeneratorExpression:async[no LineTerminator here]function*(FormalParameters){AsyncGeneratorBody}
- If the function code for this AsyncGeneratorExpression is strict mode code, let strict be true. Otherwise let strict be false.
- Let scope be the LexicalEnvironment of the running execution context.
- Let closure be ! AsyncGeneratorFunctionCreate(Normal, FormalParameters, AsyncGeneratorBody, scope, strict).
- Let prototype be ! ObjectCreate(%AsyncGeneratorPrototype%).
- Perform ! DefinePropertyOrThrow(closure,
"prototype"
, PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}). - Return closure. AsyncGeneratorExpression:async[no LineTerminator here]function*BindingIdentifier(FormalParameters){AsyncGeneratorBody}
- If the function code for this AsyncGeneratorExpression is strict mode code, let strict be true. Otherwise let strict be false.
- Let scope be the running execution context's LexicalEnvironment.
- Let funcEnv be ! NewDeclarativeEnvironment(scope).
- Let envRec be funcEnv's EnvironmentRecord.
- Let name be StringValue of BindingIdentifier.
- Perform ! envRec.CreateImmutableBinding(name).
- Let closure be ! AsyncGeneratorFunctionCreate(Normal, FormalParameters, AsyncGeneratorBody, funcEnv, strict).
- Let prototype be ! ObjectCreate(%AsyncGeneratorPrototype%).
- Perform ! DefinePropertyOrThrow(closure,
"prototype"
, PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}). - Perform ! SetFunctionName(closure, name).
- Perform ! envRec.InitializeBinding(name, closure).
- Return closure. Note
The BindingIdentifier in an AsyncGeneratorExpression can be referenced from inside the AsyncGeneratorExpression's AsyncGeneratorBody to allow the generator code to call itself recursively. However, unlike in an AsyncGeneratorDeclaration, the BindingIdentifier in an AsyncGeneratorExpression cannot be referenced from and does not affect the scope enclosing the AsyncGeneratorExpression.
9Runtime Semantics: CreateDynamicFunction(constructor, newTarget, kind, args)
Editor's Note
This patch modifies
.
The abstract operation CreateDynamicFunction is called with arguments constructor, newTarget, kind, and args. constructor is the constructor function that is performing this action, newTarget is the constructor that new
was initially applied to, kind is either "normal"
, "generator"
, or "async"
, or "async generator"
, and args is a List containing the actual argument values that were passed to constructor. The following steps are taken:
- Assert: The execution context stack has at least two elements.
- Let callerContext be the second to top element of the execution context stack.
- Let callerRealm be callerContext's Realm.
- Let calleeRealm be the current Realm Record.
- Perform ? HostEnsureCanCompileStrings(callerRealm, calleeRealm).
- If newTarget is undefined, let newTarget be constructor.
- If kind is
"normal"
, then- Let goal be the grammar symbol FunctionBody[~Yield, ~Await].
- Let parameterGoal be the grammar symbol FormalParameters[~Yield, ~Await].
- Let fallbackProto be
"%FunctionPrototype%"
.
- Else if kind is
"generator"
, then- Let goal be the grammar symbol GeneratorBody.
- Let parameterGoal be the grammar symbol FormalParameters[+Yield, ~Await].
- Let fallbackProto be
"%Generator%"
.
Else,- Else if kind is
"async"
, Assert: kind is"async"
- Let goal be the grammar symbol AsyncFunctionBody.
- Let parameterGoal be the grammar symbol FormalParameters[~Yield, +Await].
- Let fallbackProto be
"%AsyncFunctionPrototype%"
. - Else,
- Assert: kind is
"async generator"
- Let goal be the grammar symbol AsyncGeneratorBody.
- Let parameterGoal be the grammar symbol FormalParameters[+Yield, +Await].
- Let fallbackProto be
"%AsyncGenerator%"
. - Let argCount be the number of elements in args.
- Let P be the empty String.
- If argCount = 0, let bodyText be the empty String.
- Else if argCount = 1, let bodyText be args[0].
- Else argCount > 1,
- Let firstArg be args[0].
- Let P be ? ToString(firstArg).
- Let k be 1.
- Repeat, while k < argCount-1
- Let nextArg be args[k].
- Let nextArgString be ? ToString(nextArg).
- Let P be the result of concatenating the previous value of P, the String
","
(a comma), and nextArgString. - Increase k by 1.
- Let bodyText be args[k].
- Let bodyText be ? ToString(bodyText).
- Let parameters be the result of parsing P, interpreted as UTF-16 encoded Unicode text as described in 6.1.4, using parameterGoal as the goal symbol. Throw a SyntaxError exception if the parse fails.
- Let body be the result of parsing bodyText, interpreted as UTF-16 encoded Unicode text as described in 6.1.4, using goal as the goal symbol. Throw a SyntaxError exception if the parse fails.
- If bodyText is strict mode code, let strict be true, else let strict be false.
- If any static semantics errors are detected for parameters or body, throw a SyntaxError or a ReferenceError exception, depending on the type of the error. If strict is true, the Early Error rules for UniqueFormalParameters:FormalParameters are applied. Parsing and early error detection may be interweaved in an implementation-dependent manner.
- If ContainsUseStrict of body is true and IsSimpleParameterList of parameters is false, throw a SyntaxError exception.
- If any element of the BoundNames of parameters also occurs in the LexicallyDeclaredNames of body, throw a SyntaxError exception.
- If body Contains SuperCall is true, throw a SyntaxError exception.
- If parameters Contains SuperCall is true, throw a SyntaxError exception.
- If body Contains SuperProperty is true, throw a SyntaxError exception.
- If parameters Contains SuperProperty is true, throw a SyntaxError exception.
- If kind is
"generator"
or"async generator"
, then - If parameters Contains YieldExpression is true, throw a SyntaxError exception.
- If kind is
"async"
or"async generator"
, then - If parameters Contains AwaitExpression is true, throw a SyntaxError exception.
- If strict is true, then
- If BoundNames of parameters contains any duplicate elements, throw a SyntaxError exception.
- Let proto be ? GetPrototypeFromConstructor(newTarget, fallbackProto).
- Let F be FunctionAllocate(proto, strict, kind).
- Let realmF be F.[[Realm]].
- Let scope be realmF.[[GlobalEnv]].
- Perform FunctionInitialize(F, Normal, parameters, body, scope).
- If kind is
"generator"
, then - Let prototype be ObjectCreate(%GeneratorPrototype%).
- Perform DefinePropertyOrThrow(F,
"prototype"
, PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}). - Else if kind is
"async generator"
, then - Let prototype be ObjectCreate(%AsyncGeneratorPrototype%).
- Perform DefinePropertyOrThrow(F,
"prototype"
, PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}). - Else if kind is
"normal"
, perform MakeConstructor(F). - NOTE: Async functions are not constructable and do not have a [[Construct]] internal method or a
"prototype"
property. - Perform SetFunctionName(F,
"anonymous"
). - Return F. Note
A prototype
property is created for every non-async function created using CreateDynamicFunction to provide for the possibility that the function will be used as a constructor.
10Properties of the Symbol Constructor
Editor's Note
This patch add a clause to
.
10.1Symbol.asyncIterator
The initial value of Symbol.asyncIterator
is the well known symbol @@asyncIterator (Table 1).
This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
11Control Abstraction Objects
Editor's Note
These patches modify clauses of and add clauses to
.
11.1Iteration
11.1.1Common Iteration Interfaces
11.1.1.1The AsyncIterable Interface
The AsyncIterable interface includes the properties described in Table 3:
Table 3: AsyncIterable Interface Required Properties
Property | Value | Requirements |
---|---|---|
@@asyncIterator | A function that returns an AsyncIterator object. | The returned object must conform to the AsyncIterator interface. |
11.1.1.2The AsyncIterator Interface
An object that implements the AsyncIterator interface must include the properties in Table 4. Such objects may also implement the properties in Table 5.
Table 4: AsyncIterator Interface Required Properties
Property | Value | Requirements |
---|---|---|
next | A function that returns a promise for an IteratorResult object. | The returned promise, when fulfilled, must fulfill with an object which conforms to the IteratorResult interface. If a previous call to the next method of an AsyncIterator has returned a promise for an IteratorResult object whose done property is true, then all subsequent calls to the next method of that object should also return a promise for an IteratorResult object whose done property is true. However, this requirement is not enforced. Additionally, the IteratorResult object that serves as a fulfillment value should have a value property whose value is not a promise (or "thenable"). However, this requirement is also not enforced. |
Note 1
Arguments may be passed to the next function but their interpretation and validity is dependent upon the target AsyncIterator. The for
-await
-of
statement and other common users of AsyncIterators do not pass any arguments, so AsyncIterator objects that expect to be used in such a manner must be prepared to deal with being called with no arguments.
Table 5: AsyncIterator Interface Optional Properties
Property | Value | Requirements |
---|---|---|
return | A function that returns a promise for an IteratorResult object. | The returned promise, when fulfilled, must fulfill with an object which conforms to the IteratorResult interface. Invoking this method notifies the AsyncIterator object that the caller does not intend to make any more next method calls to the AsyncIterator. The returned promise will fulfill with an IteratorResult object which will typically have a done property whose value is true, and a value property with the value passed as the argument of the return method. However, this requirement is not enforced. Additionally, the IteratorResult object that serves as a fulfillment value should have a value property whose value is not a promise (or "thenable"). If the argument value is used in the typical manner, then if it is a rejected promise, a promise rejected with the same reason should be returned; if it is a fulfilled promise, then its fulfillment value should be used as the value property of the returned promise's IteratorResult object fulfillment value. However, these requirements are also not enforced. |
throw | A function that returns a promise for an IteratorResult object. | The returned promise, when fulfilled, must fulfill with an object which conforms to the IteratorResult interface. Invoking this method notifies the AsyncIterator object that the caller has detected an error condition. The argument may be used to identify the error condition and typically will be an exception object. A typical response is to return a rejected promise which rejects with the value passed as the argument. If the returned promise is fulfilled, the IteratorResult fulfillment value will typically have a done property whose value is true. Additionally, it should have a value property whose value is not a promise (or "thenable"), but this requirement is not enforced. |
Note 2
Typically callers of these methods should check for their existence before invoking them. Certain ECMAScript language features including for
-await
-of
and yield*
call these methods after performing an existence check.
11.1.2The %AsyncIteratorPrototype% Object
The value of the [[Prototype]] internal slot of the %AsyncIteratorPrototype% object is the intrinsic object %ObjectPrototype%. The %AsyncIteratorPrototype% object is an ordinary object. The initial value of the [[Extensible]] internal slot of the %AsyncIteratorPrototype% object is true.
Note
All objects defined in this specification that implement the AsyncIterator interface also inherit from %AsyncIteratorPrototype%. ECMAScript code may also define objects that inherit from %AsyncIteratorPrototype%.The %AsyncIteratorPrototype% object provides a place where additional methods that are applicable to all async iterator objects may be added.
11.1.2.1%AsyncIteratorPrototype% [ @@asyncIterator ] ( )
The following steps are taken:
- Return the this value.
The value of the name
property of this function is "[Symbol.asyncIterator]"
.
11.1.3Async-from-Sync Iterator Objects
An Async-from-Sync Iterator object is an async iterator that adapts a specific synchronous iterator. There is not a named constructor for Async-from-Sync Iterator objects. Instead, Async-from-Sync iterator objects are created by the CreateAsyncFromSyncIterator abstract operation as needed.
11.1.3.1CreateAsyncFromSyncIterator(syncIteratorRecord) Abstract Operation
The abstract operation CreateAsyncFromSyncIterator is used to create an async iterator Record from a synchronous iterator Record. It performs the following steps:
- Let asyncIterator be ! ObjectCreate(%AsyncFromSyncIteratorPrototype%, « [[SyncIteratorRecord]] »).
- Set asyncIterator.[[SyncIteratorRecord]] to syncIteratorRecord.
- Return ? GetIterator(asyncIterator, async).
11.1.3.2The %AsyncFromSyncIteratorPrototype% Object
All Async-from-Sync Iterator Objects inherit properties from the %AsyncFromSyncIteratorPrototype% intrinsic object. The %AsyncFromSyncIteratorPrototype% object is an ordinary object and its [[Prototype]] internal slot is the %AsyncIteratorPrototype% intrinsic object. In addition, %AsyncFromSyncIteratorPrototype% has the following properties:
11.1.3.2.1%AsyncFromSyncIteratorPrototype%.next ( value )
- Let O be the this value.
- Let promiseCapability be ! NewPromiseCapability(%Promise%).
- If Type(O) is not Object, or if O does not have a [[SyncIteratorRecord]] internal slot, then
- Let badIteratorError be a new TypeError exception.
- Perform ! Call(promiseCapability.[[Reject]], undefined, « badIteratorError »).
- Return promiseCapability.[[Promise]].
- Let syncIteratorRecord be O.[[SyncIteratorRecord]].
- Let nextResult be IteratorNext(syncIteratorRecord, value).
- IfAbruptRejectPromise(nextResult, promiseCapability).
- Let nextDone be IteratorComplete(nextResult).
- IfAbruptRejectPromise(nextDone, promiseCapability).
- Let nextValue be IteratorValue(nextResult).
- IfAbruptRejectPromise(nextValue, promiseCapability).
- Let valueWrapperCapability be ! NewPromiseCapability(%Promise%).
- Perform ! Call(valueWrapperCapability.[[Resolve]], undefined, « nextValue »).
- Let onFulfilled be a new built-in function object as defined in Async-from-Sync Iterator Value Unwrap Functions.
- Set onFulfilled.[[Done]] to nextDone.
- Perform ! PerformPromiseThen(valueWrapperCapability.[[Promise]], onFulfilled, undefined, promiseCapability).
- Return promiseCapability.[[Promise]].
11.1.3.2.2%AsyncFromSyncIteratorPrototype%.return ( value )
- Let O be the this value.
- Let promiseCapability be ! NewPromiseCapability(%Promise%).
- If Type(O) is not Object, or if O does not have a [[SyncIteratorRecord]] internal slot, then
- Let badIteratorError be a new TypeError exception.
- Perform ! Call(promiseCapability.[[Reject]], undefined, « badIteratorError »).
- Return promiseCapability.[[Promise]].
- Let syncIterator be O.[[SyncIteratorRecord]].[[Iterator]].
- Let return be GetMethod(syncIterator,
"return"
). - IfAbruptRejectPromise(return, promiseCapability).
- If return is undefined, then
- Let iterResult be ! CreateIterResultObject(value, true).
- Perform ! Call(promiseCapability.[[Resolve]], undefined, « iterResult »).
- Return promiseCapability.[[Promise]].
- Let returnResult be Call(return, syncIterator, « value »).
- IfAbruptRejectPromise(returnResult, promiseCapability).
- If Type(returnResult) is not Object,
- Perform ! Call(promiseCapability.[[Reject]], undefined, « a TypeError exception »).
- Return promiseCapability.[[Promise]].
- Let returnDone be IteratorComplete(returnResult).
- IfAbruptRejectPromise(returnDone, promiseCapability).
- Let returnValue be IteratorValue(returnResult).
- IfAbruptRejectPromise(returnValue, promiseCapability).
- Let valueWrapperCapability be ! NewPromiseCapability(%Promise%).
- Perform ! Call(valueWrapperCapability.[[Resolve]], undefined, « returnValue »).
- Let onFulfilled be a new built-in function object as defined in Async-from-Sync Iterator Value Unwrap Functions.
- Set onFulfilled.[[Done]] to returnDone.
- Perform ! PerformPromiseThen(valueWrapperCapability.[[Promise]], onFulfilled, undefined, promiseCapability).
- Return promiseCapability.[[Promise]].
11.1.3.2.3%AsyncFromSyncIteratorPrototype%.throw ( value )
- Let O be the this value.
- Let promiseCapability be ! NewPromiseCapability(%Promise%).
- If Type(O) is not Object, or if O does not have a [[SyncIteratorRecord]] internal slot, then
- Let badIteratorError be a new TypeError exception.
- Perform ! Call(promiseCapability.[[Reject]], undefined, « badIteratorError »).
- Return promiseCapability.[[Promise]].
- Let syncIterator be O.[[SyncIteratorRecord]].[[Iterator]].
- Let throw be GetMethod(syncIterator,
"throw"
). - IfAbruptRejectPromise(throw, promiseCapability).
- If throw is undefined, then
- Perform ! Call(promiseCapability.[[Reject]], undefined, « value »).
- Return promiseCapability.[[Promise]].
- Let throwResult be Call(throw, syncIterator, « value »).
- IfAbruptRejectPromise(throwResult, promiseCapability).
- If Type(throwResult) is not Object,
- Perform ! Call(promiseCapability.[[Reject]], undefined, « a TypeError exception »).
- Return promiseCapability.[[Promise]].
- Let throwDone be IteratorComplete(throwResult).
- IfAbruptRejectPromise(throwDone, promiseCapability).
- Let throwValue be IteratorValue(throwResult).
- IfAbruptRejectPromise(throwValue, promiseCapability).
- Let valueWrapperCapability be ! NewPromiseCapability(%Promise%).
- Perform ! Call(valueWrapperCapability.[[Resolve]], undefined, « throwValue »).
- Let onFulfilled be a new built-in function object as defined in Async-from-Sync Iterator Value Unwrap Functions.
- Set onFulfilled.[[Done]] to throwDone.
- Perform ! PerformPromiseThen(valueWrapperCapability.[[Promise]], onFulfilled, undefined, promiseCapability).
- Return promiseCapability.[[Promise]].
11.1.3.2.4%AsyncFromSyncIteratorPrototype% [ @@toStringTag ]
The initial value of the @@toStringTag property is the String value "Async-from-Sync Iterator"
.
This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
11.1.3.2.5Async-from-Sync Iterator Value Unwrap Functions
An async-from-sync iterator value unwrap function is an anonymous built-in function that is used by methods of %AsyncFromSyncIteratorPrototype% when processing the value
field of an IteratorResult object, in order to wait for its value if it is a promise and re-package the result in a new "unwrapped" IteratorResult object. Each async iterator value unwrap function has a [[Done]] internal slot.
When an async-from-sync iterator value unwrap function F is called with argument value, the following steps are taken:
- Return ! CreateIterResultObject(value, F.[[Done]]).
11.1.3.3Properties of Async-from-Sync Iterator Instances
Async-from-Sync Iterator instances are ordinary objects that inherit properties from the %AsyncFromSyncIteratorPrototype% intrinsic object. Async-from-Sync Iterator instances are initially created with the internal slots listed in Table 6.
Table 6: Internal Slots of Async-from-Sync Iterator Instances
Internal Slot | Description |
---|---|
[[SyncIteratorRecord]] | A Record, of the type returned by GetIterator, representing the original synchronous iterator which is being adapted. |
11.2Generator Objects
11.2.1Generator Abstract Operations
11.2.1.1GetGeneratorKind ( )
- Let genContext be the running execution context.
- If genContext does not have a Generator component, return non-generator.
- Let generator be the Generator component of genContext.
- If generator has an [[AsyncGeneratorState]] internal slot, return async.
- Else, return normal.
11.2.1.2GeneratorYield ( iterNextObj )
The abstract operation GeneratorYield with argument iterNextObj performs the following steps:
- Assert: iterNextObj is an Object that implements the IteratorResult interface.
- Let genContext be the running execution context.
- Assert: genContext is the execution context of a generator.
- Let generator be the value of the Generator component of genContext.
- Assert: GetGeneratorKind() is normal.
- Set generator.[[GeneratorState]] to
"suspendedYield"
. - Remove genContext 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.
- Set the code evaluation state of genContext such that when evaluation is resumed with a Completion resumptionValue the following steps will be performed:
- Return resumptionValue.
- NOTE: This returns to the evaluation of the YieldExpression that originally called this abstract operation.
- Return NormalCompletion(iterNextObj).
- NOTE: This returns to the evaluation of the operation that had most previously resumed evaluation of genContext.
11.3AsyncGeneratorFunction Objects
AsyncGenerator Function objects are functions that are usually created by evaluating AsyncGeneratorDeclaration, AsyncGeneratorExpression, and AsyncGeneratorMethod syntactic productions. They may also be created by calling the %AsyncGeneratorFunction% intrinsic.
11.3.1The AsyncGeneratorFunction Constructor
The AsyncGeneratorFunction
constructor is the %AsyncGeneratorFunction% intrinsic. When AsyncGeneratorFunction
is called as a function rather than as a constructor, it creates and initializes a new AsyncGeneratorFunction object. Thus the function call AsyncGeneratorFunction (...)
is equivalent to the object creation expression new AsyncGeneratorFunction (...)
with the same arguments.
AsyncGeneratorFunction
is designed to be subclassable. It may be used as the value of an extends
clause of a class definition. Subclass constructors that intend to inherit the specified AsyncGeneratorFunction
behaviour must include a super
call to the AsyncGeneratorFunction
constructor to create and initialize subclass instances with the internal slots necessary for built-in AsyncGeneratorFunction behaviour. All ECMAScript syntactic forms for defining async generator function objects create direct instances of AsyncGeneratorFunction
. There is no syntactic means to create instances of AsyncGeneratorFunction
subclasses.
11.3.1.1AsyncGeneratorFunction ( p1, p2, ..., pn, body )
The last argument specifies the body (executable code) of an async generator function; any preceding arguments specify formal parameters.
When the AsyncGeneratorFunction
function is called with some arguments p1, p2, … , pn, body (where n might be 0, that is, there are no "p" arguments, and where body might also not be provided), the following steps are taken:
- Let C be the active function object.
- Let args be the argumentsList that was passed to this function by [[Call]] or [[Construct]].
- Return ? CreateDynamicFunction(C, NewTarget,
"async generator"
, args). Note
11.3.2Properties of the AsyncGeneratorFunction Constructor
The AsyncGeneratorFunction
constructor is a standard built-in function object that inherits from the Function
constructor. The value of the [[Prototype]] internal slot of the AsyncGeneratorFunction
constructor is the intrinsic object %Function%.
The value of the [[Extensible]] internal slot of the AsyncGeneratorFunction constructor is true.
The value of the name
property of the AsyncGeneratorFunction is "AsyncGeneratorFunction"
.
The AsyncGeneratorFunction
constructor has the following properties:
11.3.2.1AsyncGeneratorFunction.length
This is a data property with a value of 1. This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
11.3.2.2AsyncGeneratorFunction.prototype
The initial value of AsyncGeneratorFunction.prototype
is the intrinsic object %AsyncGenerator%.
This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
11.3.3Properties of the AsyncGeneratorFunction Prototype Object
The AsyncGeneratorFunction prototype object is an ordinary object. It is not a function object and does not have an [[ECMAScriptCode]] internal slot or any other of the internal slots listed in Table 27 or Table 7. In addition to being the value of the prototype property of the %AsyncGeneratorFunction% intrinsic, it is the %AsyncGenerator% intrinsic.
The value of the [[Prototype]] internal slot of the AsyncGeneratorFunction prototype object is the %FunctionPrototype% intrinsic object. The initial value of the [[Extensible]] internal slot of the AsyncGeneratorFunction prototype object is true.
11.3.3.1AsyncGeneratorFunction.prototype.constructor
The initial value of AsyncGeneratorFunction.prototype.constructor
is the intrinsic object %AsyncGeneratorFunction%.
This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
11.3.3.2AsyncGeneratorFunction.prototype.prototype
The value of AsyncGeneratorFunction.prototype.prototype
is the %AsyncGeneratorPrototype% intrinsic object.
This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
11.3.3.3AsyncGeneratorFunction.prototype [ @@toStringTag ]
The initial value of the @@toStringTag property is the String value "AsyncGeneratorFunction"
.
This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
11.3.4AsyncGeneratorFunction Instances
Every AsyncGeneratorFunction instance is an ECMAScript function object and has the internal slots listed in Table 27. The value of the [[FunctionKind]] internal slot for all such instances is "generator"
.
Each AsyncGeneratorFunction instance has the following own properties:
11.3.4.1length
The value of the length
property is an integer that indicates the typical number of arguments expected by the AsyncGeneratorFunction. However, the language permits the function to be invoked with some other number of arguments. The behaviour of an AsyncGeneratorFunction when invoked on a number of arguments other than the number specified by its length
property depends on the function.
This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
11.3.4.2name
The specification for the name
property of Function instances given in 19.2.4.2 also applies to AsyncGeneratorFunction instances.
11.3.4.3prototype
Whenever an AsyncGeneratorFunction instance is created another ordinary object is also created and is the initial value of the async generator function's prototype
property. The value of the prototype property is used to initialize the [[Prototype]] internal slot of a newly created AsyncGenerator object when the generator function object is invoked using [[Call]].
This property has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.
Note
Unlike function instances, the object that is the value of the an AsyncGeneratorFunction's prototype
property does not have a constructor
property whose value is the AsyncGeneratorFunction instance.
11.4AsyncGenerator Objects
An AsyncGenerator object is an instance of an async generator function and conforms to both the AsyncIterator and AsyncIterable interfaces.
AsyncGenerator instances directly inherit properties from the object that is the value of the prototype
property of the AsyncGenerator function that created the instance. AsyncGenerator instances indirectly inherit properties from the AsyncGenerator Prototype intrinsic, %AsyncGeneratorPrototype%.
11.4.1Properties of AsyncGenerator Prototype
The AsyncGenerator prototype object is the %AsyncGeneratorPrototype% intrinsic. It is also the initial value of the prototype
property of the %AsyncGenerator% intrinsic (the AsyncGeneratorFunction.prototype).
The AsyncGenerator prototype is an ordinary object. It is not an AsyncGenerator instance and does not have an [[AsyncGeneratorState]] internal slot.
The value of the [[Prototype]] internal slot of the AsyncGenerator prototype object is the intrinsic object %AsyncIteratorPrototype%. The initial value of the [[Extensible]] internal slot of the AsyncGenerator prototype object is true.
All AsyncGenerator instances indirectly inherit properties of the AsyncGenerator prototype object.
11.4.1.1AsyncGenerator.prototype.constructor
The initial value of AsyncGenerator.prototype.constructor
is the intrinsic object %AsyncGenerator%.
This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
11.4.1.2AsyncGenerator.prototype.next ( value )
- Let generator be the
this
value. - Let completion be NormalCompletion(value).
- Return ! AsyncGeneratorEnqueue(generator, completion).
11.4.1.3AsyncGenerator.prototype.return ( value )
- Let generator be the
this
value. - Let completion be Completion{[[Type]]: return, [[Value]]: value, [[Target]]: empty}.
- Return ! AsyncGeneratorEnqueue(generator, completion).
11.4.1.4AsyncGenerator.prototype.throw ( exception )
- Let generator be the
this
value. - Let completion be Completion{[[Type]]: throw, [[Value]]: exception, [[Target]]: empty}.
- Return ! AsyncGeneratorEnqueue(generator, completion).
11.4.1.5AsyncGenerator.prototype [ @@toStringTag ]
The initial value of the @@toStringTag property is the String value "AsyncGenerator"
.
This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
11.4.2Properties of AsyncGenerator Instances
AsyncGenerator instances are initially created with the internal slots described below:
Table 7: Internal Slots of AsyncGenerator Instances
Internal Slot | Description |
---|---|
[[AsyncGeneratorState]] | The current execution state of the async generator. The possible values are: undefined, "suspendedStart", "suspendedYield", "executing", "awaiting-return", and "completed". |
[[AsyncGeneratorContext]] | The execution context that is used when executing the code of this async generator. |
[[AsyncGeneratorQueue]] | A List of AsyncGeneratorRequest records which represent requests to resume the async generator. |
11.4.3AsyncGenerator Abstract Operations
11.4.3.1AsyncGeneratorRequest Records
The AsyncGeneratorRequest is a Record value used to store information about how an async generator should be resumed and contains capabilities for fulfilling or rejecting the corresponding promise.
They have the following fields:
Table 8: AsyncGeneratorRequest Record Fields
Field Name | Value | Meaning |
---|---|---|
[[Completion]] | A Completion record | The completion which should be used to resume the async generator. |
[[Capability]] | A PromiseCapability record | The promise capabilities associated with this request. |
11.4.3.2AsyncGeneratorStart ( generator, generatorBody )
- Assert: generator is an AsyncGenerator instance.
- Assert: generator.[[AsyncGeneratorState]] is undefined.
- Let genContext be the running execution context.
- Set the Generator component of genContext to generator.
- Set the code evaluation state of genContext such that when evaluation is resumed for that execution context the following steps will be performed:
- Let result be the result of evaluating generatorBody.
- Assert: If we return here, the async generator either threw an exception or performed either an implicit or explicit return.
- Remove genContext 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.
- Set generator.[[AsyncGeneratorState]] to
"completed"
. - If result is a normal completion, let resultValue be undefined.
- Else,
- Let resultValue be result.[[Value]].
- If result.[[Type]] is not return, then
1. Return ! AsyncGeneratorReject(generator, resultValue).
- Return ! AsyncGeneratorResolve(generator, resultValue, true).
- Set generator.[[AsyncGeneratorContext]] to genContext.
- Set generator.[[AsyncGeneratorState]] to
"suspendedStart"
. - Set generator.[[AsyncGeneratorQueue]] to a new empty List.
- Return undefined.
11.4.3.3AsyncGeneratorResolve ( generator, value, done )
- Assert: generator is an AsyncGenerator instance.
- Let queue be generator.[[AsyncGeneratorQueue]].
- Assert: queue is not an empty List.
- Remove the first element from queue and let next be the value of that element.
- Let promiseCapability be next.[[Capability]].
- Let iteratorResult be ! CreateIterResultObject(value, done).
- Perform ! Call(promiseCapability.[[Resolve]], undefined, « iteratorResult »).
- Perform ! AsyncGeneratorResumeNext(generator).
- Return undefined.
11.4.3.4AsyncGeneratorReject ( generator, exception )
- Assert: generator is an AsyncGenerator instance.
- Let queue be generator.[[AsyncGeneratorQueue]].
- Assert: queue is not an empty List.
- Remove the first element from queue and let next be the value of that element.
- Let promiseCapability be next.[[Capability]].
- Perform ! Call(promiseCapability.[[Reject]], undefined, « exception »).
- Perform ! AsyncGeneratorResumeNext(generator).
- Return undefined.
11.4.3.5AsyncGeneratorResumeNext ( generator )
- Assert: generator is an AsyncGenerator instance.
- Let state be generator.[[AsyncGeneratorState]].
- Assert: state is not
"executing"
. - If state is
"awaiting-return"
, return undefined. - Let queue be generator.[[AsyncGeneratorQueue]].
- If queue is an empty List, return undefined.
- Let next be the value of the first element of queue.
- Assert: next is an AsyncGeneratorRequest record.
- Let completion be next.[[Completion]].
- If completion is an abrupt completion, then
- If state is
"suspendedStart"
, then- Set generator.[[AsyncGeneratorState]] to
"completed"
. - Set state to
"completed"
.
- Set generator.[[AsyncGeneratorState]] to
- If state is
"completed"
, then- If completion.[[Type]] is return:
1. Set generator.[[AsyncGeneratorState]] to"awaiting-return"
.
2. Let promiseCapability be ! NewPromiseCapability(%Promise%).
3. Perform ! Call(promiseCapability.[[Resolve]], undefined, « completion.[[Value]] »).
4. Let onFulfilled be a new built-in function object as defined in AsyncGeneratorResumeNext Return Processor Fulfilled Functions.
5. Let onRejected be a new built-in function object as defined in AsyncGeneratorResumeNext Return Processor Rejected Functions.
6. Set onFulfilled and onRejected's [[Generator]] internal slots to generator.
7. Let throwawayCapability be NewPromiseCapability(%Promise%).
8. Set throwawayCapability.[[Promise]].[[PromiseIsHandled]] to true.
9. Perform ! PerformPromiseThen(promiseCapability.[[Promise]], onFulfilled, onRejected, throwawayCapability).
10. Return undefined. - Else,
1. Assert: completion.[[Type]] is throw.
2. Perform ! AsyncGeneratorReject(generator, completion.[[Value]]).
3. Return undefined.
- If completion.[[Type]] is return:
- Else if state is
"completed"
, then return ! AsyncGeneratorResolve(generator, undefined, true). - Assert: state is either
"suspendedStart"
or"suspendedYield"
. - Let genContext be generator.[[AsyncGeneratorContext]].
- Let callerContext be the running execution context.
- Suspend callerContext.
- Set generator.[[AsyncGeneratorState]] to
"executing"
. - Push genContext onto the execution context stack; genContext is now the running execution context.
- Resume the suspended evaluation of genContext using completion as the result of the operation that suspended it. Let result be the completion record returned by the resumed computation.
- Assert: result is never an abrupt completion.
- Assert: When we return here, genContext has already been removed from the execution context stack and callerContext is the currently running execution context.
- Return undefined.
11.4.3.5.1AsyncGeneratorResumeNext Return Processor Fulfilled Functions
An AsyncGeneratorResumeNext return processor fulfilled function is an anonymous built-in function that is used as part of the AsyncGeneratorResumeNext specification device to unwrap promises passed in to the AsyncGenerator.prototype.return ( value ) method. Each AsyncGeneratorResumeNext return processor fulfilled function has a [[Generator]] internal slot.
When an AsyncGeneratorResumeNext return processor fulfilled function F is called with argument value, the following steps are taken:
- Set F.[[Generator]].[[AsyncGeneratorState]] to
"completed"
. - Return ! AsyncGeneratorResolve(F.[[Generator]], value, true).
The length
property of an AsyncGeneratorResumeNext return processor fulfilled function is 1.
11.4.3.5.2AsyncGeneratorResumeNext Return Processor Rejected Functions
An AsyncGeneratorResumeNext return processor rejected function is an anonymous built-in function that is used as part of the AsyncGeneratorResumeNext specification device to unwrap promises passed in to the AsyncGenerator.prototype.return ( value ) method. Each AsyncGeneratorResumeNext return processor rejected function has a [[Generator]] internal slot.
When an AsyncGeneratorResumeNext return processor rejected function F is called with argument reason, the following steps are taken:
- Set F.[[Generator]].[[AsyncGeneratorState]] to
"completed"
. - Return ! AsyncGeneratorReject(F.[[Generator]], reason).
The length
property of an AsyncGeneratorResumeNext return processor rejected function is 1.
11.4.3.6AsyncGeneratorEnqueue ( generator, completion )
- Assert: completion is a Completion Record.
- Let promiseCapability be ! NewPromiseCapability(%Promise%).
- If Type(generator) is not Object, or if generator does not have an [[AsyncGeneratorState]] internal slot, then
- Let badGeneratorError be a new TypeError exception.
- Perform ! Call(promiseCapability.[[Reject]], undefined, « badGeneratorError »).
- Return promiseCapability.[[Promise]].
- Let queue be generator.[[AsyncGeneratorQueue]].
- Let request be AsyncGeneratorRequest{[[Completion]]: completion, [[Capability]]: promiseCapability}.
- Append request to the end of queue.
- Let state be generator.[[AsyncGeneratorState]].
- If state is not
"executing"
, then- Perform ! AsyncGeneratorResumeNext(generator).
- Return promiseCapability.[[Promise]].
11.4.3.7AsyncGeneratorYield ( value )
The abstract operation AsyncGeneratorYield with argument value performs the following steps:
- Let genContext be the running execution context.
- Assert: genContext is the execution context of a generator.
- Let generator be the value of the Generator component of genContext.
- Assert: GetGeneratorKind() is async.
- Set value to ? Await(value).
- Set generator.[[AsyncGeneratorState]] to
"suspendedYield"
. - Remove genContext 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.
- Set the code evaluation state of genContext such that when evaluation is resumed with a Completion resumptionValue the following steps will be performed:
- If resumptionValue.[[Type]] is not return, return Completion(resumptionValue).
- Let awaited be Await(resumptionValue.[[Value]]).
- If awaited.[[Type]] is throw, return Completion(awaited).
- Assert: awaited.[[Type]] is normal.
- Return Completion{[[Type]]: return, [[Value]]: awaited.[[Value]], [[Target]]: empty}.
- NOTE: When one of the above steps returns, it returns to the evaluation of the YieldExpression production that originally called this abstract operation.
- Return ! AsyncGeneratorResolve(generator, value, false).
- NOTE: This returns to the evaluation of the operation that had most previously resumed evaluation of genContext.
12Miscellaneous Patches
The specification contains many locations which mention generators that also should be updated to mention async generators. The ones with significant normative impact have been patched above. Here we attempt to enumerate all other places that will need minor updates.
- Global Environment Records must mention AsyncGenerationDeclaration wherever it mentions GeneratorDeclaration.
- Types of Source Code must mention AsyncGeneratorDeclaration and AsyncGeneratorExpression, as well as "Async Generator Definitions (8.3)" in the NOTE.
- Strict Mode Code must mention AsyncGeneratorDeclaration, AsyncGeneratorExpression, and the
AsyncGenerator
constructor. - PrimaryExpression must contain AsyncGeneratorExpression, and all places that reference it and include GeneratorExpression should also include AsyncGeneratorExpression.
- Function Defining Expressions must have the additional sentence "See 8.3 for PrimaryExpression:AsyncGeneratorExpression ."
- HoistableDeclaration must contain AsyncGeneratorDeclaration (appropriately parametrized).
- Static Semantics: DeclarationPart must contain an analogous line for AsyncGeneratorDeclaration.
- Runtime Semantics: Evaluation must add AsyncGeneratorDeclaration to the case that currently contains only GeneratorDeclaration.
- Runtime Semantics: BlockDeclarationInstantiation( code, env ) must be expanded to include AsyncGeneratorDeclaration in addition to GeneratorDeclaration and FunctionDeclaration.
- MethodDefinition must contain AsyncGeneratorMethod (appropriately parametrized).
- Runtime Semantics: PropertyDefinitionEvaluation must contain an analogous "See 8.3" line for AsyncGeneratorMethod.
- Static Semantics: IsInTailPosition( nonterminal ) must be updated to mention AsyncGeneratorBody alongside GeneratorBody.
- Runtime Semantics: GlobalDeclarationInstantiation ( script, env ) must be updated to mention AsyncGeneratorDeclaration alongside FunctionDeclaration and GeneratorDeclaration.
- ModuleDeclarationInstantiation( ) Concrete Method must be updated to mention AsyncGeneratorDeclaration alongside FunctionDeclaration and GeneratorDeclaration.
- Forbidden Extensions must be updated to mention the various parallel async generator constructs alongside the usual ones in the
"caller"
and"arguments"
prohibitions. - Runtime Semantics: EvalDeclarationInstantiation( body, varEnv, lexEnv, strict ) must be updated to mention AsyncGeneratorDeclaration alongside FunctionDeclaration and GeneratorDeclaration.
- The Function Constructor must also reference the
AsyncGeneratorFunction
subclass. - Function.prototype.toString ( ) must reference AsyncGeneratorDeclaration, AsyncGeneratorExpression, and AsyncGeneratorMethod in the appropriately-analogous places.
- prototype must also exclude MethodDefinitions that are AsyncGeneratorMethods.
- The NOTE in the upcoming "Async Function Definitions" section must also mention AsyncGeneratorBody and its related FormalParameters.