Stage 2 Draft / August 26, 2021

Iterator Helpers

Contributing to this Proposal

This proposal is developed on GitHub with the help of the ECMAScript community. There are a number of ways to contribute to the development of this specification:

1 Well-Known Intrinsic Objects

Table 1: Well-Known Intrinsic Objects
Intrinsic Name Global Name ECMAScript Language Association
%AsyncIterator% AsyncIterator The AsyncIterator constructor (3.1.3.1)
%AsyncIteratorPrototype% AsyncIterator.prototype An object that all standard built-in async iterator objects indirectly inherit from

The initial value of the "prototype" data property of %AsyncIterator%; i.e., %AsyncIterator.prototype%

%Iterator% Iterator The Iterator constructor (3.1.2.1)
%IteratorPrototype% Iterator.prototype An object that all standard built-in iterator objects indirectly inherit from

The initial value of the "prototype" data property of %Iterator%; i.e., %Iterator.prototype%

2 Abstract Operations

2.1 Operations on Iterator Objects

2.1.1 GetIteratorDirect ( obj )

  1. If Type(obj) is not Object, throw a TypeError exception.
  2. Let nextMethod be ? GetV(obj, "next").
  3. If IsCallable(nextMethod) is false, throw a TypeError exception.
  4. Let iteratorRecord be Record { [[Iterator]]: obj, [[NextMethod]]: nextMethod, [[Done]]: false }.
  5. Return iteratorRecord.

2.1.2 IteratorStep ( iteratorRecord [ , value ] )

  1. Let result be ? IteratorNext(iteratorRecord).
  2. If value is present, then
    1. Let result be ? IteratorNext(iteratorRecord, value).
  3. Else,
    1. Let result be ? IteratorNext(iteratorRecord).
  4. Let done be ? IteratorComplete(result).
  5. If done is true, return false.
  6. Return result.

3 Control Abstraction Objects

3.1 Iteration

3.1.1 Iterator Abstract Operations

3.1.1.1 IfAbruptCloseAsyncIterator ( value, iteratorRecord )

IfAbruptCloseAsyncIterator is a shorthand for a sequence of algorithm steps that use an Iterator Record. An algorithm step of the form:

  1. IfAbruptCloseAsyncIterator(value, iteratorRecord).

means the same thing as:

  1. If value is an abrupt completion, then
    1. Perform ? AsyncIteratorClose(iteratorRecord, value).
    2. Return value.
  2. Else if value is a Completion Record, set value to value.[[Value]].

3.1.2 Iterator Objects

3.1.2.1 The Iterator Constructor

The Iterator constructor:

  • is %Iterator%.
  • is the initial value of the Iterator property of the global object.
  • is designed to be subclassable. It may be used as the value of an extends clause of a class definition.

3.1.2.1.1 Iterator ( )

When the Iterator function is called, the following steps are taken:

  1. If NewTarget is undefined or the active function object, throw a TypeError exception.
  2. Return ? OrdinaryCreateFromConstructor(NewTarget, "%Iterator.prototype%").

3.1.2.2 Properties of the Iterator Constructor

3.1.2.2.1 Iterator.prototype

The initial value of Iterator.prototype is %Iterator.prototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

3.1.2.2.2 Iterator.from ( O )

  1. Let usingIterator be ? GetMethod(O, @@iterator).
  2. If usingIterator is not undefined,
    1. Let iteratorRecord be ? GetIterator(O, sync, usingIterator).
    2. Let hasInstance be ? OrdinaryHasInstance(%Iterator%, iteratorRecord.[[Iterator]]).
    3. If hasInstance is true, then
      1. Return iteratorRecord.[[Iterator]].
  3. Else, Let iteratorRecord be ? GetIteratorDirect(O).
  4. Let wrapper be ! ObjectCreate(%WrapForValidIteratorPrototype%, « [[Iterated]] »).
  5. Set wrapper.[[Iterated]] to iteratorRecord.
  6. Return wrapper.

3.1.2.2.2.1 The %WrapForValidIteratorPrototype% Object

The %WrapForValidIteratorPrototype% object:

3.1.2.2.2.1.1 %WrapForValidIteratorPrototype%.next ( value )

  1. Let O be this value.
  2. RequireInternalSlot(O, [[Iterated]]).
  3. If value is not present, then
    1. Return ? IteratorNext(O.[[Iterated]]).
  4. Else,
    1. Return ? IteratorNext(O.[[Iterated]], value).

3.1.2.2.2.1.2 %WrapForValidIteratorPrototype%.return ( v )

  1. Let O be this value.
  2. RequireInternalSlot(O, [[Iterated]]).
  3. Let result be ? IteratorClose(O.[[Iterated]], NormalCompletion(v)).
  4. Return CreateIterResultObject(result, true).

3.1.2.2.2.1.3 %WrapForValidIteratorPrototype%.throw ( v )

  1. Let O be this value.
  2. RequireInternalSlot(O, [[Iterated]]).
  3. Let iterator be O.[[Iterated]].[[Iterator]].
  4. Let throw be ? GetMethod(iterator, "throw").
  5. If throw is undefined, return ThrowCompletion(v).
  6. Otherwise, return ? Call(throw, iterator, « v »).

3.1.3 AsyncIterator Objects

3.1.3.1 The AsyncIterator Constructor

The AsyncIterator constructor:

  • is %AsyncIterator%.
  • is the initial value of the AsyncIterator property of the global object.
  • is designed to be subclassable. It may be used as the value of an extends clause of a class definition.

3.1.3.1.1 AsyncIterator ( )

When the AsyncIterator function is called, the following steps are taken:

  1. If NewTarget is undefined or the active function object, throw a TypeError exception.
  2. Return ? OrdinaryCreateFromConstructor(NewTarget, "%AsyncIterator.prototype%").

3.1.3.2 Properties of the AsyncIterator Constructor

3.1.3.2.1 AsyncIterator.prototype

The initial value of AsyncIterator.prototype is %AsyncIterator.prototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

3.1.3.2.2 AsyncIterator.from ( O )

  1. Let usingIterator be ? GetMethod(O, @@asyncIterator).
  2. If usingIterator is not undefined,
    1. Let iteratorRecord be ? GetIterator(O, async, usingIterator).
    2. Let hasInstance be ? OrdinaryHasInstance(%AsyncIterator.prototype%, iteratorRecord.[[Iterator]]).
    3. If hasInstance is true, then
      1. Return iteratorRecord.[[Iterator]].
  3. If iteratorRecord is undefined,
    1. Set usingIterator to ? GetMethod(O, @@iterator).
    2. If usingIterator is not undefined,
      1. Let syncIteratorRecord be ? GetIterator(O, sync, usingIterator).
      2. Return ! CreateAsyncFromSyncIterator(syncIteratorRecord).
  4. If iteratorRecord is undefined, set iteratorRecord to ? GetIteratorDirect(O).
  5. Let wrapper be ! ObjectCreate(%WrapForValidAsyncIteratorPrototype%, « [[AsyncIterated]] »).
  6. Set wrapper.[[AsyncIterated]] to iteratorRecord.
  7. Return wrapper.

3.1.4 Iterator Helper Objects

An Iterator Helper object is an ordinary object that represents a lazy transformation of some specific source iterator object. There is not a named constructor for Iterator Helper objects. Instead, Iterator Helper objects are created by calling certain methods of Iterator instance objects.

3.1.4.1 The %IteratorHelperPrototype% Object

The %IteratorHelperPrototype% object:

  • has properties that are inherited by all Iterator Helper Objects.
  • is an ordinary object.
  • has a [[Prototype]] internal slot whose value is %Iterator.prototype%.
  • has the following properties:

3.1.4.1.1 %IteratorHelperPrototype%.next ( value )

  1. Return ? GeneratorResume(this value, value, Iterator Helper).

3.1.4.1.2 %IteratorHelperPrototype%.return ( value )

  1. Let C be Completion { [[Type]]: return, [[Value]]: value, [[Target]]: empty }.
  2. Return ? GeneratorResumeAbrupt(this value, C, Iterator Helper).

3.1.4.1.3 %IteratorHelperPrototype%.throw ( exception )

  1. Let C be ThrowCompletion(exception).
  2. Return ? GeneratorResumeAbrupt(this value, C, Iterator Helper).

3.1.4.1.4 %IteratorHelperPrototype% [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "Iterator Helper".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

3.1.5 Async Iterator Helper Objects

An Async Iterator Helper object is an ordinary object that represents a lazy transformation of some specific source async iterator object. There is not a named constructor for Async Iterator Helper objects. Instead, Async Iterator Helper objects are created by calling certain methods of AsyncIterator instance objects.

3.1.5.1 The %AsyncIteratorHelperPrototype% Object

The %AsyncIteratorHelperPrototype% object:

  • has properties that are inherited by all Async Iterator Helper Objects.
  • is an ordinary object.
  • has a [[Prototype]] internal slot whose value is %AsyncIterator.prototype%.
  • has the following properties:

3.1.5.1.1 %AsyncIteratorHelperPrototype%.next ( value )

  1. Let C be NormalCompletion(value).
  2. Return ! AsyncGeneratorEnqueue(this value, C, Async Iterator Helper).

3.1.5.1.2 %AsyncIteratorHelperPrototype%.return ( value )

  1. Let C be Completion { [[Type]]: return, [[Value]]: value, [[Target]]: empty }.
  2. Return ! AsyncGeneratorEnqueue(this value, C, Async Iterator Helper).

3.1.5.1.3 %AsyncIteratorHelperPrototype%.throw ( exception )

  1. Let C be ThrowCompletion(exception).
  2. Return ! AsyncGeneratorEnqueue(this value, C, Async Iterator Helper).

3.1.5.1.4 %AsyncIteratorHelperPrototype% [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "Async Iterator Helper".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

3.1.6 The %Iterator.prototype% Object

3.1.6.1 %Iterator.prototype%.constructor

The initial value of %Iterator.prototype%.constructor is %Iterator%.

3.1.6.2 %Iterator.prototype%.map ( mapper )

  1. Let iterated be ? GetIteratorDirect(this value).
  2. If IsCallable(mapper) is false, throw a TypeError exception.
  3. Let closure be a new Abstract Closure with no parameters that captures iterated and mapper and performs the following steps when called:
    1. Let lastValue be undefined.
    2. Repeat,
      1. Let next be ? IteratorStep(iterated, lastValue).
      2. If next is false, return undefined.
      3. Let value be ? IteratorValue(next).
      4. Let mapped be Call(mapper, undefined, « value »).
      5. IfAbruptCloseIterator(iterated, mapped).
      6. Set lastValue to Yield(mapped).
      7. IfAbruptCloseIterator(iterated, lastValue).
  4. Return ? CreateIteratorFromClosure(closure, Iterator Helper, %IteratorHelperPrototype%).

3.1.6.3 %Iterator.prototype%.filter ( filterer )

  1. Let iterated be ? GetIteratorDirect(this value).
  2. If IsCallable(filterer) is false, throw a TypeError exception.
  3. Let closure be a new Abstract Closure with no parameters that captures iterated and filterer and performs the following steps when called:
    1. Let lastValue be undefined.
    2. Repeat,
      1. Let next be ? IteratorStep(iterated, lastValue).
      2. If next is false, return undefined.
      3. Let value be ? IteratorValue(next).
      4. Let selected be Call(filterer, undefined, « value »).
      5. IfAbruptCloseIterator(iterated, selected).
      6. If ! ToBoolean(selected) is true,
        1. Set lastValue to Yield(value).
        2. IfAbruptCloseIterator(iterated, lastValue).
  4. Return ? CreateIteratorFromClosure(closure, Iterator Helper, %IteratorHelperPrototype%).

3.1.6.4 %Iterator.prototype%.take ( limit )

  1. Let iterated be ? GetIteratorDirect(this value).
  2. Let integerLimit be ? ToIntegerOrInfinity(limit).
  3. If integerLimit < 0, throw a RangeError exception.
  4. Let closure be a new Abstract Closure with no parameters that captures iterated and integerLimit and performs the following steps when called:
    1. Let remaining be integerLimit.
    2. Let lastValue be undefined.
    3. Repeat,
      1. If remaining is 0, then
        1. Return ? IteratorClose(iterated, NormalCompletion(undefined)).
      2. If remaining is not +∞, then
        1. Set remaining to remaining - 1.
      3. Let next be ? IteratorStep(iterated, lastValue).
      4. If next is false, return undefined.
      5. Set lastValue to Yield(? IteratorValue(next)).
      6. IfAbruptCloseIterator(iterated, lastValue).
  5. Return ? CreateIteratorFromClosure(closure, Iterator Helper, %IteratorHelperPrototype%).

3.1.6.5 %Iterator.prototype%.drop ( limit )

  1. Let iterated be ? GetIteratorDirect(this value).
  2. Let integerLimit be ? ToIntegerOrInfinity(limit).
  3. If integerLimit < 0, throw a RangeError exception.
  4. Let closure be a new Abstract Closure with no parameters that captures iterated and integerLimit and performs the following steps when called:
    1. Let remaining be integerLimit.
    2. Repeat, while remaining > 0,
      1. If remaining is not +∞, then
        1. Set remaining to remaining - 1.
      2. Let next be ? IteratorStep(iterated).
      3. If next is false, return undefined.
    3. Let lastValue be undefined.
    4. Repeat,
      1. Let next be ? IteratorStep(iterated, lastValue).
      2. If next is false, return undefined.
      3. Set lastValue to Yield(? IteratorValue(next)).
      4. IfAbruptCloseIterator(iterated, lastValue).
  5. Return ? CreateIteratorFromClosure(closure, Iterator Helper, %IteratorHelperPrototype%).

3.1.6.6 %Iterator.prototype%.asIndexedPairs ( )

  1. Let iterated be ? GetIteratorDirect(this value).
  2. Let closure be a new Abstract Closure with no parameters that captures iterated and performs the following steps when called:
    1. Let index be 0.
    2. Let lastValue be undefined.
    3. Repeat,
      1. Let next be ? IteratorStep(iterated, lastValue).
      2. If next is false, return undefined.
      3. Let value be ? IteratorValue(next).
      4. Let pair be ! CreateArrayFromListindex, value »).
      5. Set index to index + 1.
      6. Set lastValue to Yield(pair).
      7. IfAbruptCloseIterator(iterated, lastValue).
  3. Return ? CreateIteratorFromClosure(closure, Iterator Helper, %IteratorHelperPrototype%).

3.1.6.7 %Iterator.prototype%.flatMap ( mapper )

  1. Let iterated be ? GetIteratorDirect(this value).
  2. If IsCallable(mapper) is false, throw a TypeError exception.
  3. Let closure be a new Abstract Closure with no parameters that captures iterated and mapper and performs the following steps when called:
    1. Repeat,
      1. Let next be ? IteratorStep(iterated).
      2. If next is false, return undefined.
      3. Let value be ? IteratorValue(next).
      4. Let mapped be Call(mapper, undefined, « value »).
      5. IfAbruptCloseIterator(mapped, iterated).
      6. Let innerIterator be GetIterator(mapped, sync).
      7. IfAbruptCloseIterator(innerIterator, iterated).
      8. Let innerAlive be true.
      9. Repeat, while innerAlive is true,
        1. Let innerNext be IteratorNext(innerIterator).
        2. IfAbruptCloseIterator(innerNext, iterated).
        3. Let innerComplete be IteratorComplete(innerNext).
        4. IfAbruptCloseIterator(innerComplete, iterated).
        5. If innerComplete is true, set innerAlive to false.
        6. Else,
          1. Let innerValue be IteratorValue(innerNext).
          2. IfAbruptCloseIterator(innerValue, iterated).
          3. Let yielded be Yield(innerValue).
          4. IfAbruptCloseIterator(yielded, iterated).
  4. Return ? CreateIteratorFromClosure(closure, Iterator Helper, %IteratorHelperPrototype%).

3.1.6.8 %Iterator.prototype%.reduce ( reducer [ , initialValue ] )

  1. Let iterated be ? GetIteratorDirect(this value).
  2. If IsCallable(reducer) is false, throw a TypeError exception.
  3. If initialValue is not present, then
    1. Let next be ? IteratorStep(iterated).
    2. If next is false, throw a TypeError exception.
    3. Let accumulator be ? IteratorValue(next).
  4. Else,
    1. Let accumulator be initialValue.
  5. Repeat,
    1. Let next be ? IteratorStep(iterated).
    2. If next is false, return accumulator.
    3. Let value be ? IteratorValue(next).
    4. Let result be Call(reducer, undefined, « accumulator, value »).
    5. IfAbruptCloseIterator(result, iterated).
    6. Set accumulator to result.[[Value]].

3.1.6.9 %Iterator.prototype%.toArray ( )

  1. Let iterated be ? GetIteratorDirect(this value).
  2. Let items be a new empty List.
  3. Repeat,
    1. Let next be ? IteratorStep(iterated).
    2. If next is false, return ! CreateArrayFromList(items).
    3. Let value be ? IteratorValue(next).
    4. Append value to items.

3.1.6.10 %Iterator.prototype%.forEach ( fn )

  1. Let iterated be ? GetIteratorDirect(this value).
  2. If IsCallable(fn) is false, throw a TypeError exception.
  3. Repeat,
    1. Let next be ? IteratorStep(iterated).
    2. If next is false, return undefined.
    3. Let value be ? IteratorValue(next).
    4. Let result be Call(fn, undefined, « value »).
    5. IfAbruptCloseIterator(result, iterated).

3.1.6.11 %Iterator.prototype%.some ( fn )

  1. Let iterated be ? GetIteratorDirect(this value).
  2. If IsCallable(fn) is false, throw a TypeError exception.
  3. Repeat,
    1. Let next be ? IteratorStep(iterated).
    2. If next is false, return false.
    3. Let value be ? IteratorValue(next).
    4. Let result be Call(fn, undefined, « value »).
    5. IfAbruptCloseIterator(result, iterated).
    6. If ! ToBoolean(result) is true, return ? IteratorClose(iterated, NormalCompletion(true)).

3.1.6.12 %Iterator.prototype%.every ( fn )

  1. Let iterated be ? GetIteratorDirect(this value).
  2. If IsCallable(fn) is false, throw a TypeError exception.
  3. Repeat,
    1. Let next be ? IteratorStep(iterated).
    2. If next is false, return true.
    3. Let value be ? IteratorValue(next).
    4. Let result be Call(fn, undefined, « value »).
    5. IfAbruptCloseIterator(result, iterated).
    6. If ! ToBoolean(result) is false, return ? IteratorClose(iterated, NormalCompletion(false)).

3.1.6.13 %Iterator.prototype%.find ( fn )

  1. Let iterated be ? GetIteratorDirect(this value).
  2. If IsCallable(fn) is false, throw a TypeError exception.
  3. Repeat,
    1. Let next be ? IteratorStep(iterated).
    2. If next is false, return undefined.
    3. Let value be ? IteratorValue(next).
    4. Let result be Call(fn, undefined, « value »).
    5. IfAbruptCloseIterator(result, iterated).
    6. If ! ToBoolean(result) is true, return ? IteratorClose(iterated, NormalCompletion(value)).

3.1.6.14 %Iterator.prototype% [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "Iterator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

3.1.7 The %AsyncIterator.prototype% Object

3.1.7.1 %AsyncIterator.prototype%.constructor

The initial value of %AsyncIterator.prototype%.constructor is %AsyncIterator%.

3.1.7.2 %AsyncIterator.prototype%.map ( mapper )

  1. Let iterated be ? GetIteratorDirect(this value).
  2. If IsCallable(mapper) is false, throw a TypeError exception.
  3. Let closure be a new Abstract Closure with no parameters that captures iterated and mapper and performs the following steps when called:
    1. Let lastValue be undefined.
    2. Repeat,
      1. Let next be ? Await(? IteratorNext(value, lastValue)).
      2. If ? IteratorComplete(next) is true, return undefined.
      3. Let value be ? IteratorValue(next).
      4. Let mapped be Call(mapper, undefined, « value »).
      5. IfAbruptCloseAsyncIterator(iterated, mapped).
      6. Set mapped to Await(mapped).
      7. IfAbruptCloseAsyncIterator(iterated, mapped).
      8. Set lastValue to Yield(mapped).
      9. IfAbruptCloseAsyncIterator(iterated, lastValue).
  4. Return ? CreateAsyncIteratorFromClosure(closure, Async Iterator Helper, %AsyncIteratorHelperPrototype%).

3.1.7.3 %AsyncIterator.prototype%.filter ( filterer )

  1. Let iterated be ? GetIteratorDirect(this value).
  2. If IsCallable(filterer) is false, throw a TypeError exception.
  3. Let closure be a new Abstract Closure with no parameters that captures iterated and filterer and performs the following steps when called:
    1. Let lastValue be undefined.
    2. Repeat,
      1. Let next be ? Await(? IteratorNext(value, lastValue)).
      2. If ? IteratorComplete(next) is true, return undefined.
      3. Let value be ? IteratorValue(next).
      4. Let selected be Call(filterer, undefined, « value »).
      5. IfAbruptCloseAsyncIterator(iterated, selected).
      6. Set selected to Await(selected).
      7. IfAbruptCloseAsyncIterator(iterated, selected).
      8. If ! ToBoolean(selected) is true, then
        1. Set lastValue to Yield(value).
        2. IfAbruptCloseAsyncIterator(iterated, lastValue).
  4. Return ? CreateAsyncIteratorFromClosure(closure, Async Iterator Helper, %AsyncIteratorHelperPrototype%).

3.1.7.4 %AsyncIterator.prototype%.take ( limit )

  1. Let iterated be ? GetIteratorDirect(this value).
  2. Let integerLimit be ? ToIntegerOrInfinity(limit).
  3. If integerLimit < 0, throw a RangeError exception.
  4. Let closure be a new Abstract Closure with no parameters that captures iterated and integerLimit and performs the following steps when called:
    1. Let remaining be integerLimit.
    2. Let lastValue be undefined.
    3. Repeat,
      1. If remaining is 0, then
        1. Return ? AsyncIteratorClose(iterated, NormalCompletion(undefined)).
      2. If remaining is not +∞, then
        1. Set remaining to remaining - 1.
      3. Let next be ? Await(? IteratorNext(iterated, lastValue)).
      4. If ? IteratorComplete(next) is true, return undefined.
      5. Set lastValue to Yield(? IteratorValue(next)).
      6. IfAbruptCloseAsyncIterator(iterated, lastValue).
  5. Return ? CreateAsyncIteratorFromClosure(closure, Async Iterator Helper, %AsyncIteratorHelperPrototype%).

3.1.7.5 %AsyncIterator.prototype%.drop ( limit )

  1. Let iterated be ? GetIteratorDirect(this value).
  2. Let integerLimit be ? ToIntegerOrInfinity(limit).
  3. If integerLimit < 0, throw a RangeError exception.
  4. Let closure be a new Abstract Closure with no parameters that captures iterated and integerLimit and performs the following steps when called:
    1. Let remaining be integerLimit.
    2. Repeat, while remaining > 0,
      1. If remaining is not +∞, then
        1. Set remaining to remaining - 1.
      2. Let next be ? Await(? IteratorNext(iterated)).
      3. If ? IteratorComplete(next) is true, return undefined.
    3. Let lastValue be undefined.
    4. Repeat,
      1. Let next be ? Await(? IteratorNext(iterated, lastValue)).
      2. If ? IteratorComplete(next) is true, return undefined.
      3. Set lastValue to Yield(? IteratorValue(next)).
      4. IfAbruptCloseAsyncIterator(iterated, lastValue).
  5. Return ? CreateAsyncIteratorFromClosure(closure, Async Iterator Helper, %AsyncIteratorHelperPrototype%).

3.1.7.6 %AsyncIterator.prototype%.asIndexedPairs ( )

  1. Let iterated be ? GetIteratorDirect(this value).
  2. Let closure be a new Abstract Closure with no parameters that captures iterated and performs the following steps when called:
    1. Let index be 0.
    2. Let lastValue be undefined.
    3. Repeat,
      1. Let next be ? Await(? IteratorNext(iterated, lastValue)).
      2. If ? IteratorComplete(next) is true, return undefined.
      3. Let value be ? IteratorValue(next).
      4. Let pair be ! CreateArrayFromListindex, value »).
      5. Set index to index + 1.
      6. Set lastValue to Yield(pair).
      7. IfAbruptCloseAsyncIterator(iterated, lastValue).
  3. Return ? CreateAsyncIteratorFromClosure(closure, Async Iterator Helper, %AsyncIteratorHelperPrototype%).

3.1.7.7 %AsyncIterator.prototype%.flatMap ( mapper )

%AsyncIterator.prototype%.flatMap is a built-in async generator function which, when called, performs the following steps:

  1. Let iterated be ? GetIteratorDirect(this value).
  2. If IsCallable(mapper) is false, throw a TypeError exception.
  3. Let closure be a new Abstract Closure with no parameters that captures iterated and mapper and performs the following steps when called:
    1. Repeat,
      1. Let next be ? Await(? IteratorNext(iterated)).
      2. If ? IteratorComplete(next) is true, return undefined.
      3. Let value be ? IteratorValue(next).
      4. Let mapped be Call(mapper, undefined, « value »).
      5. IfAbruptCloseAsyncIterator(iterated, mapped).
      6. Set mapped to Await(mapped).
      7. IfAbruptCloseAsyncIterator(iterated, mapped).
      8. Let innerIterator be GetIterator(mapped, async).
      9. IfAbruptCloseAsyncIterator(innerIterator, iterated).
      10. Let innerAlive be true.
      11. Repeat, while innerAlive is true,
        1. Let innerNextPromise be IteratorNext(innerIterator).
        2. IfAbruptCloseAsyncIterator(innerNextPromise, iterated).
        3. Let innerNext be Await(innerNextPromise).
        4. IfAbruptCloseAsyncIterator(innerNext, iterated).
        5. Let innerComplete be IteratorComplete(innerNext).
        6. IfAbruptCloseAsyncIterator(innerComplete, iterated).
        7. If innerComplete is true, set innerAlive to false.
        8. Else,
          1. Let innerValue be IteratorValue(innerNext).
          2. IfAbruptCloseAsyncIterator(innerValue, iterated).
          3. Let yielded be Yield(innerValue).
          4. IfAbruptCloseAsyncIterator(yielded, iterated).
  4. Return ? CreateAsyncIteratorFromClosure(closure, Async Iterator Helper, %AsyncIteratorHelperPrototype%).

3.1.7.8 %AsyncIterator.prototype%.reduce ( reducer [ , initialValue ] )

  1. Let iterated be ? GetIteratorDirect(this value).
  2. If IsCallable(reducer) is false, throw a TypeError exception.
  3. If initialValue is not present, then
    1. Let next be ? Await(? IteratorNext(iterated)).
    2. If ? IteratorComplete(next) is true, throw a TypeError exception.
    3. Let accumulator be ? IteratorValue(next).
  4. Else,
    1. Let accumulator be initialValue.
  5. Repeat,
    1. Let next be ? Await(? IteratorNext(iterated)).
    2. If ? IteratorComplete(next) is true, return accumulator.
    3. Let value be ? IteratorValue(next).
    4. Let result be Call(reducer, undefined, « accumulator, value »).
    5. IfAbruptCloseAsyncIterator(iterated, result).
    6. Set result to Await(result).
    7. IfAbruptCloseAsyncIterator(iterated, result).
    8. Set accumulator to result.

3.1.7.9 %AsyncIterator.prototype%.toArray ( )

%AsyncIterator.prototype%.toArray is a built-in async function which, when called, performs the following steps:

  1. Let iterated be ? GetIteratorDirect(this value).
  2. Let items be a new empty List.
  3. Repeat,
    1. Let next be ? Await(? IteratorNext(iterated)).
    2. If ? IteratorComplete(next) is true, return ! CreateArrayFromList(items).
    3. Let value be ? IteratorValue(next).
    4. Append value to items.

3.1.7.10 %AsyncIterator.prototype%.forEach ( fn )

%AsyncIterator.prototype%.forEach is a built-in async function which, when called, performs the following steps:

  1. Let iterated be ? GetIteratorDirect(this value).
  2. If IsCallable(fn) is false, throw a TypeError exception.
  3. Repeat,
    1. Let next be ? Await(? IteratorNext(iterated)).
    2. If ? IteratorComplete(next) is true, return undefined.
    3. Let value be ? IteratorValue(next).
    4. Let r be Call(fn, undefined, « value »).
    5. IfAbruptCloseAsyncIterator(iterated, r).
    6. Set r to Await(r).
    7. IfAbruptCloseAsyncIterator(iterated, r).

3.1.7.11 %AsyncIterator.prototype%.some ( fn )

%AsyncIterator.prototype%.some is a built-in async function which, when called, performs the following steps:

  1. Let iterated be ? GetIteratorDirect(this value).
  2. If IsCallable(fn) is false, throw a TypeError exception.
  3. Repeat,
    1. Let next be ? Await(? IteratorNext(iterated)).
    2. If ? IteratorComplete(next) is true, return false.
    3. Let value be ? IteratorValue(next).
    4. Let result be Call(fn, undefined, « value »).
    5. IfAbruptCloseAsyncIterator(iterated, result).
    6. Set result to Await(result).
    7. IfAbruptCloseAsyncIterator(iterated, result).
    8. If ! ToBoolean(result) is true, return ? AsyncIteratorClose(iterated, NormalCompletion(true)).

3.1.7.12 %AsyncIterator.prototype%.every ( fn )

%AsyncIterator.prototype%.every is a built-in async function which, when called, performs the following steps:

  1. Let iterated be ? GetIteratorDirect(this value).
  2. If IsCallable(fn) is false, throw a TypeError exception.
  3. Repeat,
    1. Let next be ? Await(? IteratorNext(iterated)).
    2. If ? IteratorComplete(next) is true, return true.
    3. Let value be ? IteratorValue(next).
    4. Let result be Call(fn, undefined, « value »).
    5. IfAbruptCloseAsyncIterator(iterated, result).
    6. Set result to Await(result).
    7. IfAbruptCloseAsyncIterator(iterated, result).
    8. If ! ToBoolean(result) is false, return ? AsyncIteratorClose(iterated, NormalCompletion(false)).

3.1.7.13 %AsyncIterator.prototype%.find ( fn )

%AsyncIterator.prototype%.find is a built-in async function which, when called, performs the following steps:

  1. Let iterated be ? GetIteratorDirect(this value).
  2. If IsCallable(fn) is false, throw a TypeError exception.
  3. Repeat,
    1. Let next be ? Await(? IteratorNext(iterated)).
    2. If ? IteratorComplete(next) is true, return undefined.
    3. Let value be ? IteratorValue(next).
    4. Let result be Call(fn, undefined, « value »).
    5. IfAbruptCloseAsyncIterator(iterated, result).
    6. Set result to Await(result).
    7. IfAbruptCloseAsyncIterator(iterated, result).
    8. If ! ToBoolean(result) is true, return ? AsyncIteratorClose(iterated, NormalCompletion(value)).

3.1.7.14 %AsyncIterator.prototype% [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "Async Iterator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

3.1.8 The %AsyncFromSyncIteratorPrototype% Object

3.1.8.1 %AsyncFromSyncIteratorPrototype%.next ( value )

  1. Let O be the this value.
  2. Assert: Type(O) is Object and O has a [[SyncIteratorRecord]] internal slot.
  3. Let promiseCapability be ! NewPromiseCapability(%Promise%).
  4. Let check be RequireInternalSlot(O, [[SyncIteratorRecord]]).
  5. IfAbruptRejectPromise(check, promiseCapability).
  6. Let syncIteratorRecord be O.[[SyncIteratorRecord]].
  7. Let result be IteratorNext(syncIteratorRecord, value).
  8. IfAbruptRejectPromise(result, promiseCapability).
  9. Return ! AsyncFromSyncIteratorContinuation(result, promiseCapability).

3.1.8.2 %AsyncFromSyncIteratorPrototype%.return ( value )

  1. Let O be the this value.
  2. Assert: Type(O) is Object and O has a [[SyncIteratorRecord]] internal slot.
  3. Let promiseCapability be ! NewPromiseCapability(%Promise%).
  4. Let check be RequireInternalSlot(O, [[SyncIteratorRecord]]).
  5. IfAbruptRejectPromise(check, promiseCapability).
  6. Let return be GetMethod(syncIterator, "return").
  7. IfAbruptRejectPromise(return, promiseCapability).
  8. If return is undefined, then
    1. Let iterResult be ! CreateIterResultObject(value, true).
    2. Perform ! Call(promiseCapability.[[Resolve]], undefined, « iterResult »).
    3. Return promiseCapability.[[Promise]].
  9. Let result be Call(return, syncIterator, « value »).
  10. IfAbruptRejectPromise(result, promiseCapability).
  11. If Type(result) is not Object, then
    1. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »).
    2. Return promiseCapability.[[Promise]].
  12. Return ! AsyncFromSyncIteratorContinuation(result, promiseCapability).

3.1.8.3 %AsyncFromSyncIteratorPrototype%.throw ( value )

  1. Let O be the this value.
  2. Assert: Type(O) is Object and O has a [[SyncIteratorRecord]] internal slot.
  3. Let promiseCapability be ! NewPromiseCapability(%Promise%).
  4. Let check be RequireInternalSlot(O, [[SyncIteratorRecord]]).
  5. IfAbruptRejectPromise(check, promiseCapability).
  6. Let syncIterator be O.[[SyncIteratorRecord]].[[Iterator]].
  7. Let throw be GetMethod(syncIterator, "throw").
  8. IfAbruptRejectPromise(throw, promiseCapability).
  9. If throw is undefined, then
    1. Perform ! Call(promiseCapability.[[Reject]], undefined, « value »).
    2. Return promiseCapability.[[Promise]].
  10. Let result be Call(throw, syncIterator, « value »).
  11. IfAbruptRejectPromise(result, promiseCapability).
  12. If Type(result) is not Object, then
    1. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »).
    2. Return promiseCapability.[[Promise]].
  13. Return ! AsyncFromSyncIteratorContinuation(result, promiseCapability).