- From: Domenic Denicola <notifications@github.com>
- Date: Tue, 21 May 2019 18:53:42 +0000 (UTC)
- To: heycam/webidl <webidl@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <heycam/webidl/pull/720/review/240228152@github.com>
domenic commented on this pull request.
Overall LGTM! A few clarity suggestions.
> +being iterated over asynchronously to obtain a sequence of values.
+
+Note: In the ECMAScript language binding, an interface that is asynchronously iterable will have
+<code class="idl">entries</code>, <code class="idl">keys</code>, <code class="idl">values</code>,
+and {{@@asyncIterator}} properties on its [=interface prototype object=].
+
+Prose accompanying an [=interface=] with an [=asynchronously iterable declaration=] must define a
+<dfn id="dfn-get-the-next-iteration-result">get the next iteration result</dfn> algorithm.
+This algorithm receives a <b>[=this=]</b> value, which is an instance of the [=interface=] that it
+is defined for, and the <dfn export>current state</dfn>.
+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,
Can we omit the opaque value, and have people just store any relevant state on their `this`?
> @@ -11577,6 +11725,45 @@ and the String "<code>values</code>"
if the interface has a [=setlike declaration=].
+<h5 id="es-async-iterator">@@asyncIterator</h5>
+
+If the [=interface=] has an [=asynchronously iterable declaration=], then a property must exist
+whose name is the {{@@asyncIterator}} symbol, with attributes
+{ \[[Writable]]: <emu-val>true</emu-val>, \[[Enumerable]]: <emu-val>false</emu-val>, \[[Configurable]]: <emu-val>true</emu-val> }
+and whose value is a [=function object=].
+
+The location of the property is determined as follows:
+
+* If the interface was declared with the [{{Global}}] [=extended attribute=],
+ then the property exists on the single object that [=implements=] the interface.
+* Otherwise, the property exists solely on the interface’s [=interface prototype object=].
Kind of sad to add to the declaratively-added properties list, but oh well, this is probably easier for now.
> +An [=interface=] must not have more than one [=asynchronously iterable declaration=].
+The [=inherited interfaces=] of an [=interface=] with an [=asynchronously iterable declaration=]
+must not also have an [=asynchronously iterable declaration=].
+An [=interface=] with an [=asynchronously iterable declaration=] and its [=inherited interfaces=]
+must not have a [=maplike declaration=], [=setlike declaration=], or [=iterable declaration=].
+
+The following extended attributes are applicable to [=asynchronously iterable declarations=]:
+[{{Exposed}}],
+[{{SecureContext}}].
+
+Issue: these [=extended attributes=] are not currently taken into account.
+When they are, the effect will be as you would expect.
+
+<pre class="grammar" id="prod-AsyncIterable">
+ AsyncIterable :
+ "async_iterable" "<" TypeWithExtendedAttributes "," TypeWithExtendedAttributes ">" ";"
Streams will also need some side effects on acquiring the iterator (i.e. calling the function)
> +It serves as the prototype for [=default asynchronous iterator objects=] for the interface.
+
+The \[[Prototype]] [=internal slot=] of an [=asynchronous iterator prototype object=] must be
+{{%AsyncIteratorPrototype%}}.
+
+<div algorithm="to invoke the next property of asynchronous iterators">
+
+ An [=asynchronous iterator prototype object=] must have a <code class="idl">next</code> data
+ property with attributes
+ { \[[Writable]]: <emu-val>true</emu-val>, \[[Enumerable]]: <emu-val>true</emu-val>, \[[Configurable]]: <emu-val>true</emu-val> }
+ and whose value is a [=built-in function object=] that behaves as follows:
+
+ 1. Let |interface| be the [=interface=] for which the
+ [=asynchronous iterator prototype object=] exists.
+
+ 1. Let |thisValidationPromiseCapability| be [=!=] [$NewPromiseCapability$]({{%Promise%}}).
If we had a PromiseReject abstract op, you could just create and return a new promise inline each time. I guess we'd wait for #490 for that.
> </div>
The [=class string=] of an [=iterator prototype object=] for a given [=interface=]
is the result of concatenating the [=identifier=] of the [=interface=]
and the string "<code> Iterator</code>".
+<h5 id="es-default-asynchronous-iterator-object">Default asynchronous iterator objects</h5>
+
+A <dfn id="dfn-default-asynchronous-iterator-object" export>default asynchronous iterator object</dfn>
+for a given [=interface=], target and iteration kind is an object whose \[[Prototype]]
+[=internal slot=] is the [=asynchronous iterator prototype object=] for the [=interface=].
+
+A [=default asynchronous iterator object=] has internal values:
+
+* its <em>target</em>, which is an object whose values are to be iterated,
Can we made these dfns, and cross-link to them?
> + 1. If |object|'s ongoing promise is not undefined, then:
+ 1. Let |afterOngoingPromiseCapability| be [=!=] [$NewPromiseCapability$]({{%Promise%}}).
+ 1. Let |onFulfilled| be [=!=] [$CreateBuiltinFunction$](|nextSteps|, « »).
+ 1. Perform [=!=] [$PerformPromiseThen$](|object|'s ongoing promise, |onFulfilled|,
+ <emu-val>undefined</emu-val>, |afterOngoingPromiseCapability|).
+ 1. Set |object|'s ongoing promise to |afterOngoingPromiseCapability|.\[[Promise]].
+
+ 1. Otherwise:
+ 1. Run |nextSteps| and set |object|'s ongoing promise to the result.
+
+ 1. Return |object|'s ongoing promise.
+</div>
+
+Issue: 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
+"<code> Iterator</code>".
I guess `" AsyncIterator"`?
> +being iterated over asynchronously to obtain a sequence of values.
+
+Note: In the ECMAScript language binding, an interface that is asynchronously iterable will have
+<code class="idl">entries</code>, <code class="idl">keys</code>, <code class="idl">values</code>,
+and {{@@asyncIterator}} properties on its [=interface prototype object=].
+
+Prose accompanying an [=interface=] with an [=asynchronously iterable declaration=] must define a
+<dfn id="dfn-get-the-next-iteration-result">get the next iteration result</dfn> algorithm.
+This algorithm receives a <b>[=this=]</b> value, which is an instance of the [=interface=] that it
+is defined for, and the <dfn export>current state</dfn>.
+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,
Oh, I see we cannot, because it needs to be *per iterator instance*, not *per interface instance*. Can you add an explanation to that effect?
--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/heycam/webidl/pull/720#pullrequestreview-240228152
Received on Tuesday, 21 May 2019 18:54:16 UTC