diff --git a/index.bs b/index.bs index 76894bb9..19f55816 100644 --- a/index.bs +++ b/index.bs @@ -83,6 +83,7 @@ urlPrefix: https://tc39.github.io/ecma262/; spec: ECMA-262 text: Promise; url: sec-promise-objects text: Set; url: sec-set-objects text: SharedArrayBuffer; url: sec-sharedarraybuffer-objects + text: %AsyncIteratorPrototype%; url: sec-asynciteratorprototype text: %ErrorPrototype%; url: sec-properties-of-the-error-prototype-object text: %FunctionPrototype%; url: sec-properties-of-the-function-prototype-object text: %IteratorPrototype%; url: sec-%iteratorprototype%-object @@ -106,6 +107,7 @@ urlPrefix: https://tc39.github.io/ecma262/; spec: ECMA-262 text: %PromiseProto_then%; url: sec-promise.prototype.then type: const; for: ECMAScript url: sec-well-known-symbols + text: @@asyncIterator text: @@iterator text: @@toStringTag text: @@unscopables @@ -134,6 +136,7 @@ urlPrefix: https://tc39.github.io/ecma262/; spec: ECMA-262 text: GetFunctionRealm; url: sec-getfunctionrealm text: GetIterator; url: sec-getiterator text: GetMethod; url: sec-getmethod + text: IfAbruptRejectPromise; url: sec-ifabruptrejectpromise text: IsAccessorDescriptor; url: sec-isaccessordescriptor text: IsCallable; url: sec-iscallable text: IsConstructor; url: sec-isconstructor @@ -144,6 +147,7 @@ urlPrefix: https://tc39.github.io/ecma262/; spec: ECMA-262 text: IteratorStep; url: sec-iteratorstep text: IteratorValue; url: sec-iteratorvalue text: NewModuleEnvironment; url: sec-newmoduleenvironment + text: NewPromiseCapability; url: sec-newpromisecapability text: NormalCompletion; url: sec-normalcompletion text: ObjectCreate; url: sec-objectcreate text: OrdinaryDefineOwnProperty; url: sec-ordinarydefineownproperty @@ -1070,6 +1074,7 @@ The qualified name of an [=interface=] |interface| is defined as foll Stringifier StaticMember Iterable + AsyncIterable ReadOnlyMember ReadWriteAttribute ReadWriteMaplike @@ -1196,8 +1201,9 @@ describe the behaviors that can be implemented by an object, as if they were specified on the [=interface=] that [=includes=] them. [=Static attributes=], [=static operations=], [=special operations=] except for [=stringifiers=], and -[=iterable declaration|iterable=], [=maplike declaration|maplike=], and [=setlike declarations=] -cannot appear in [=interface mixin=] declarations. +[=iterable declaration|iterable=], [=asynchronously iterable declaration|asynchronously iterable=], +[=maplike declaration|maplike=], and [=setlike declarations=] cannot appear in [=interface mixin=] +declarations. As with interfaces, the IDL for [=interface mixins=] can be split into multiple parts by using partial interface mixin definitions @@ -1554,6 +1560,13 @@ and summarized in the following informative table:
- The [=value pairs to iterate over=] are the list of key-value pairs with the key being the username and the - value being the open@@ -4130,8 +4150,9 @@ must not also have an An interface with an [=iterable declaration=] and its [=inherited interfaces=] must not have a -[=maplike declaration=] or -[=setlike declaration=]. +[=maplike declaration=], +[=setlike declaration=], or +[=asynchronously iterable declaration=]. The following extended attributes are applicable to [=iterable declarations=]: [{{Exposed}}], @@ -4149,6 +4170,144 @@ The following extended attributes are applicable to [=iterable declarations=]: +Session
object on theSessionManager
+ The [=value pairs to iterate over=] are the list of [=value pairs=] with the + [=value pair/key=] being the username and the [=value pair/value=] being the open +Session
object on theSessionManager
object corresponding to that username, sorted by username.
+ interface interface_identifier { + async iterable<key_type, value_type>; + }; ++ +Objects that [=implement=] an [=interface=] that is declared to be asynchronously iterable support +being iterated over asynchronously to obtain a sequence of values. + +Note: In the ECMAScript language binding, an interface that is asynchronously iterable will have +
entries
, keys
, values
,
+and {{@@asyncIterator}} properties on its [=interface prototype object=].
+
+Prose accompanying an [=interface=] with an [=asynchronously iterable declaration=] must define a
+get the next iteration result algorithm.
+This algorithm receives a [=this=] value, which is an instance of the [=interface=] that it
+is defined for, and the current state.
+It must return a {{Promise}} that either resolves with undefined – to signal the end of the
+iteration – or a tuple with three elements:
+
+1. a value of the first type given in the declaration;
+1. a value of the second type given in the declaration;
+1. an opaque value that is passed back to the next invocation of the algorithm as the
+ [=current state=].
+
+The prose may also define asynchronous iterator initialization steps for the
+[=interface=] with an [=asynchronously iterable declaration=], which would then be called with the
+newly created iterator object.
+
+[=Interfaces=] with an [=asynchronously iterable declaration=] must not have any
+[=interface members=] named "entries
", "keys
", or "values
",
+or have any [=inherited interfaces=] that have [=interface members=] with these names.
+
+SessionManager
, which allows access
+ to a number of Session
objects keyed by username:
+
+ + [Exposed=Window] + interface SessionManager { + Session getSessionForUser(DOMString username); + + async iterable<DOMString, Session>; + }; + + [Exposed=Window] + interface Session { + readonly attribute DOMString username; + // ... + }; ++ + The behavior of the iterator could be defined like so: + +
+ + To [=get the next iteration result=] for+ + In the ECMAScript language binding, the [=interface prototype object=] for the +SessionManager
, run the + following steps: + + 1. Let |promise| be a new promise. + 1. Let |key| be the following value, if it exists, or null otherwise: ++ : If current state is "not yet started" + :: the smallest username in this's open sessions, in lexicographical order + + : Otherwise + :: the smallest username in this's open sessions that is greater than + current state, in lexicographical order +
+ + Note: current state might no longer be present in the open sessions. + 1. If |key| is null, then: + 1. Resolve |promise| with undefined. + 1. Otherwise: + 1. Let |session| be theSession
object corresponding to |key|. + 1. Resolve |promise| with (|username|, |session|, |username|). + 1. Return |promise|. + +
SessionManager
[=interface=] has a values
method that is a
+ function, which, when invoked, returns an asynchronous iterator object that itself has a
+ next
method that returns the next value to be iterated over.
+ It has keys
and entries
methods that iterate over the usernames of
+ session objects and (username, Session
) object pairs, respectively.
+ It also has a {{@@asyncIterator}} method that allows a SessionManager
+ to be used in a for await..of
loop that has the same value as the
+ entries
method:
+
+ + // Get an instance of SessionManager. + // Assume that it has sessions for two users, "anna" and "brian". + var sm = getSessionManager(); + + typeof SessionManager.prototype.values; // Evaluates to "function" + var it = sm.values(); // values() returns an iterator object + typeof it.next; // Evaluates to "function" + + // This loop will log "anna" and then "brian". + for await (let username of sm.keys()) { + console.log(username); + } + + // Yet another way of accomplishing the same. + for await (let [username, session] of sm) { + console.log(username); + } ++
+ AsyncIterable : + "async" "iterable" "<" TypeWithExtendedAttributes "," TypeWithExtendedAttributes ">" ";" ++ +
values
"
if the interface has a [=setlike declaration=].
+@@asyncIterator
", and
+ * the type "method
".
+ 1. Let |interface| be the [=interface=] on which the [=asynchronously iterable declaration=]
+ is declared.
+ 1. If |object| does not [=implement=] |interface|, then [=ECMAScript/throw=] a
+ {{ECMAScript/TypeError}}.
+ 1. Let |iterator| be a newly created [=default asynchronous iterator object=] for |interface|
+ with |object| as its [=default asynchronous iterator object/target=] and
+ "key+value
" as its [=default asynchronous iterator object/kind=].
+ 1. Run the [=asynchronous iterator initialization steps=] for |interface| with |iterator|, if
+ any.
+ 1. Return |iterator|.
+length
property
+is the Number value name
property
+is the String value "entries
".
+
+
forEach
".
entries
data property must exist with attributes
{ \[[Writable]]: keys
data property must exist with attributes
{ \[[Writable]]: keys
", and
* the type "method
".
1. Let |interface| be the [=interface=]
- on which the [=iterable declaration=] is declared on.
+ on which the [=iterable declaration=] is declared.
1. If |object| does not [=implement=] |interface|,
then [=ECMAScript/throw=] a {{ECMAScript/TypeError}}.
1. Let |iterator| be a newly created [=default iterator object=]
@@ -11693,6 +11899,28 @@ then the [=function object=] is {{%ArrayProto_keys%}}.
1. Return |iterator|.
keys
", and
+ * the type "method
".
+ 1. Let |interface| be the [=interface=] on which the [=asynchronously iterable declaration=]
+ is declared.
+ 1. If |object| does not [=implement=] |interface|, then [=ECMAScript/throw=] a
+ {{ECMAScript/TypeError}}.
+ 1. Let |iterator| be a newly created [=default asynchronous iterator object=] for |interface|
+ with |object| as its [=default asynchronous iterator object/target=] and
+ "key
" as its [=default asynchronous iterator object/kind=].
+ 1. Run the [=asynchronous iterator initialization steps=] for |interface| with |iterator|, if
+ any.
+ 1. Return |iterator|.
+length
property is the Number value name
property is the String value "keys
".
@@ -11700,8 +11928,7 @@ The value of the [=function object=]’s name
property
values
data property must exist
with attributes { \[[Writable]]: entries
", and
* the type "method
".
1. Let |interface| be the [=interface=]
- on which the [=iterable declaration=] is declared on.
+ on which the [=iterable declaration=] is declared.
1. If |object| does not [=implement=] |interface|,
then [=ECMAScript/throw=] a {{ECMAScript/TypeError}}.
1. Let |iterator| be a newly created [=default iterator object=]
@@ -11736,6 +11963,28 @@ the value of the {{@@iterator}} property.
1. Return |iterator|.
+entries
", and
+ * the type "method
".
+ 1. Let |interface| be the [=interface=] on which the [=asynchronously iterable declaration=]
+ is declared.
+ 1. If |object| does not [=implement=] |interface|, then [=ECMAScript/throw=] a
+ {{ECMAScript/TypeError}}.
+ 1. Let |iterator| be a newly created [=default asynchronous iterator object=] for |interface|
+ with |object| as its [=default asynchronous iterator object/target=] and
+ "value
" as its [=default asynchronous iterator object/kind=].
+ 1. Run the [=asynchronous iterator initialization steps=] for |interface| with |iterator|, if
+ any.
+ 1. Return |iterator|.
+length
property is the Number value name
property is the String value "values
".
@@ -11783,6 +12032,33 @@ for the interface.
The \[[Prototype]] [=internal slot=] of an [=iterator prototype object=]
must be {{%IteratorPrototype%}}.
+key
"
+ :: 1. Let |idlKey| be |pair|’s [=value pair/key=].
+ 1. Let |key| be the result of [=converted to an ECMAScript value|converting=] |idlKey| to an ECMAScript value.
+ 1. |result| is |key|.
+ : "value
"
+ :: 1. Let |idlValue| be |pair|’s [=value pair/value=].
+ 1. Let |value| be the result of [=converted to an ECMAScript value|converting=] |idlValue| to an ECMAScript value.
+ 1. |result| is |value|.
+ : "key+value
"
+ :: 1. Let |idlKey| be |pair|’s [=value pair/key=].
+ 1. Let |idlValue| be |pair|’s [=value pair/value=].
+ 1. Let |key| be the result of [=converted to an ECMAScript value|converting=] |idlKey| to an ECMAScript value.
+ 1. Let |value| be the result of [=converted to an ECMAScript value|converting=] |idlValue| to an ECMAScript value.
+ 1. Let |array| be the result of performing [$ArrayCreate$](2).
+ 1. Call [$CreateDataProperty$](|array|, "0
", |key|).
+ 1. Call [$CreateDataProperty$](|array|, "1
", |value|).
+ 1. |result| is |array|.
+ next
data property with attributes
@@ -11807,27 +12083,7 @@ must be {{%IteratorPrototype%}}.
return CreateIterResultObject(key
"
- :: 1. Let |idlKey| be |pair|’s key.
- 1. Let |key| be the result of [=converted to an ECMAScript value|converting=] |idlKey| to an ECMAScript value.
- 1. |result| is |key|.
- : "value
"
- :: 1. Let |idlValue| be |pair|’s value.
- 1. Let |value| be the result of [=converted to an ECMAScript value|converting=] |idlValue| to an ECMAScript value.
- 1. |result| is |value|.
- : "key+value
"
- :: 1. Let |idlKey| be |pair|’s key.
- 1. Let |idlValue| be |pair|’s value.
- 1. Let |key| be the result of [=converted to an ECMAScript value|converting=] |idlKey| to an ECMAScript value.
- 1. Let |value| be the result of [=converted to an ECMAScript value|converting=] |idlValue| to an ECMAScript value.
- 1. Let |array| be the result of performing ArrayCreate(2).
- 1. Call CreateDataProperty(|array|, "0
", |key|).
- 1. Call CreateDataProperty(|array|, "1
", |value|).
- 1. |result| is |array|.
- Iterator
".
+Object.prototype.toString()
is called on a
+[=default asynchronous iterator object=] of a given [=interface=], the [=class string=] of the
+[=asynchronous iterator prototype object=] of that [=interface=] is used.
+
+
+next
data
+ property with attributes { \[[Writable]]: next
", and
+ * the type "method
".
+
+ If this threw an exception |e|, then:
+ 1. Perform [=!=] [$Call$](|thisValidationPromiseCapability|.\[[Reject]],
+ return
; throw
methods?
+
+The [=class string=] of an [=asynchronous iterator prototype object=] for a given [=interface=] is
+the result of concatenating the [=identifier=] of the [=interface=] and the string
+" AsyncIterator
".
+
+