Skip to content

Commit

Permalink
Add a non-promise version of "fully reading" a stream
Browse files Browse the repository at this point in the history
This makes it easier for non-JS consumers of streams,
like the Fetch specs, to use streams without a JS
execution context.

See whatwg/fetch#1568
  • Loading branch information
noamr committed Dec 12, 2022
1 parent 839a5a6 commit f3ca53f
Showing 1 changed file with 15 additions and 10 deletions.
25 changes: 15 additions & 10 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -6809,36 +6809,41 @@ a chunk</dfn> from a {{ReadableStreamDefaultReader}} |reader|, given a [=read re

<div algorithm="read all bytes">
<p>To <dfn export for="ReadableStreamDefaultReader" lt="read all bytes|reading all bytes">read all
bytes</dfn> from a {{ReadableStreamDefaultReader}} |reader|, perform the following steps. The
result will be a {{Promise}} for a [=byte sequence=].
bytes as a promise</dfn> from a {{ReadableStreamDefaultReader}} |reader|, perform the following
steps. The result will be a {{Promise}} for a [=byte sequence=].

1. Let |promise| be [=a new promise=].
1. Let |bytes| be an empty [=byte sequence=].
1. [=Read-loop=] given |reader|, |bytes|, and |promise|.
1. Return |promise|.
1. Let |success steps| given a [=byte sequence=] |data| be to [=resolve=] |promise| with |data|.
1. Let |failure steps| given a JavaScript value |error| be to [=reject=] |promise| with |error|.
1. [=Consume all bytes=] from |reader| given |success steps| and |failure steps|.

<p>To <dfn export for="ReadableStreamDefaultReader">consume all bytes</dfn> from
{{ReadableStreamDefaultReader}} |reader|, given |success steps|, which is an algorithm accepting a
[=byte sequence=], and |failure steps|, which is an algorithm accepting a JavaScript value,
[=read-loop=] given |reader|, a new [=byte sequence=], |success steps|, and |failure steps|.

<div algorithm="read-loop">
For the purposes of the above algorithm, to <dfn>read-loop</dfn> given |reader|, |bytes|, and
|promise|:
For the purposes of the above algorithm, to <dfn>read-loop</dfn> given |reader|, |bytes|,
|success steps|, and |failure steps|:

1. Let |readRequest| be a new [=read request=] with the following [=struct/items=]:
: [=read request/chunk steps=], given |chunk|
::
1. If |chunk| is not a {{Uint8Array}} object, [=reject=] |promise| with a {{TypeError}} and
abort these steps.
1. Append the bytes represented by |chunk| to |bytes|.
1. [=Read-loop=] given |reader|, |bytes|, and |promise|.
1. [=Read-loop=] given |reader|, |bytes|, |success steps| and |failure steps|.
<p class="note">This recursion could potentially cause a stack overflow if implemented
directly. Implementations will need to mitigate this, e.g. by using a non-recursive variant
of this algorithm, or [=queue a microtask|queuing a microtask=], or using a more direct
method of byte-reading as noted below.

: [=read request/close steps=]
::
1. [=Resolve=] |promise| with |bytes|.
1. Call |success steps| with |bytes|.
: [=read request/error steps=], given |e|
::
1. [=Reject=] |promise| with |e|.
1. Call |failure steps| with |e|.
1. Perform ! [$ReadableStreamDefaultReaderRead$](|reader|, |readRequest|).
</div>

Expand Down

0 comments on commit f3ca53f

Please sign in to comment.