Description
A blocker for #963 is expanding Web IDL's async iterator support to be powerful enough for readable streams. The tracking issue over there is whatwg/webidl#800.
On this side I want to record a draft of the algorithms. After the following get done:
- Tweak async iterator algorithms webidl#802
- Async iterators should be allowed to have an optional return() algorithm webidl#804
- Async iterator get next steps should be allowed to reject webidl#803
- The actual async iterator PR tracked in Extending async iterators to support streams webidl#800
then it will look something like this:
Async iterator initialization steps, given a ReadableStream
stream, async iterator iterator, and argument options:
- Let reader be ? AcquireReadableStreamDefaultReader(stream).
- Set iterator.[[reader]] to reader.
- Set iterator.[[preventCancel]] to options["
preventCancel
"].
To get the next iteration result for ReadableStream
given the async iterator iterator:
- Let promise be a new promise.
- Let reader be iterator.[[reader]].
- If reader.[[ownerReadableStream]] is undefined, return a promise rejected with a
TypeError
exception. - Return the result of reacting to ! ReadableStreamDefaultReaderRead(reader) with a fulfillment handler that takes an argument result and performs the following steps:
- Assert: Type(result) is Object.
- Let done be ! Get(result, "
done
"). - Assert: Type(done) is Boolean.
- If done is true,
- Perform ! ReadableStreamReaderGenericRelease(reader).
- Return undefined.
- Let value be ! Get(result, "
value
"). - Return _value.
(The above will become a bit cleaner if we are able to move away from using actual ES objects for read results, which will likely happen as part of the general Web IDL conversion.)
To close the async iterator for ReadableStream
given the async iterator iterator and argument value:
- Let reader be iterator.[[asyncIteratorReader]].
- If reader.[[ownerReadableStream]] is undefined, return a promise rejected with a
TypeError
exception. - If reader.[[readRequests]] is not empty, return a promise rejected with a
TypeError
exception. - If iterator.[[preventCancel]] is false, then:
- Let result be ! ReadableStreamReaderGenericCancel(reader, value).
- Perform ! ReadableStreamReaderGenericRelease(reader).
- Return result.
- Perform ! ReadableStreamReaderGenericRelease(reader).
- Return a promise resolved with undefined.
I think this all works, so that's good.