Skip to content

Commit

Permalink
Editorial: stop using promises in internal algorithms
Browse files Browse the repository at this point in the history
They are not designed for that and don't work well (e.g., resolve expects a JS value).

Follows whatwg/streams#1250 and addresses the Fetch part of whatwg/streams#1178.

Closes #1568.

Co-authored-by: Domenic Denicola <d@domenic.me>
Co-authored-by: Anne van Kesteren <annevk@annevk.nl>
  • Loading branch information
3 people committed Dec 22, 2022
1 parent 2d78995 commit 464326e
Showing 1 changed file with 78 additions and 79 deletions.
157 changes: 78 additions & 79 deletions fetch.bs
Expand Up @@ -1465,32 +1465,19 @@ null), run these steps. <var>processBody</var> must be an algorithm accepting a
<li><p>If <var>taskDestination</var> is null, then set <var>taskDestination</var> to the result of
<a>starting a new parallel queue</a>.

<li><p>Let <var>promise</var> be the result of <a>fully reading body as promise</a> given
<var>body</var>.

<li><p>Let <var>fulfilledSteps</var> given a <a>byte sequence</a> <var>bytes</var> be to
<li><p>Let <var>successSteps</var> given a <a>byte sequence</a> <var>bytes</var> be to
<a>queue a fetch task</a> to run <var>processBody</var> given <var>bytes</var>, with
<var>taskDestination</var>.

<li><p>Let <var>rejectedSteps</var> be to <a>queue a fetch task</a> to run
<li><p>Let <var>errorSteps</var> be to <a>queue a fetch task</a> to run
<var>processBodyError</var>, with <var>taskDestination</var>.

<li><p><a for=promise>React</a> to <var>promise</var> with <var>fulfilledSteps</var> and
<var>rejectedSteps</var>.
</ol>
</div>

<div algorithm>
<p>To <dfn export lt="fully reading body as promise">fully read body as promise</dfn>, given a
<a for=/>body</a> <var>body</var>, run these steps:

<ol>
<li><p>Let <var>reader</var> be the result of <a for=ReadableStream>getting a reader</a> for
<var>body</var>'s <a for=body>stream</a>. If that threw an exception, then return
<a>a promise rejected with</a> that exception.
<var>body</var>'s <a for=body>stream</a>. If that threw an exception, then run
<var>errorSteps</var> with that exception and return.

<li><p>Return the result of <a for=ReadableStreamDefaultReader>reading all bytes</a> from
<var>reader</var>.
<li><p><a for=ReadableStreamDefaultReader>Read all bytes</a> from
<var>reader</var>, given <var>successSteps</var> and <var>errorSteps</var>.
</ol>
</div>

Expand Down Expand Up @@ -6886,38 +6873,78 @@ returns failure or a <a for=/>MIME type</a>.

<hr>

<div algorithm>
<p>The <dfn attribute for=Body><code>body</code></dfn> getter steps are to return null if
<a>this</a>'s <a for=Body>body</a> is null; otherwise <a>this</a>'s <a for=Body>body</a>'s
<a for=body>stream</a>.
</div>

<div algorithm>
<p>The <dfn attribute for=Body><code>bodyUsed</code></dfn> getter steps are to return true if
<a>this</a>'s <a for=Body>body</a> is non-null and <a>this</a>'s <a for=Body>body</a>'s
<a for=body>stream</a> is <a for=ReadableStream>disturbed</a>; otherwise false.
</div>

<p>The <dfn id=concept-body-package-data for=Body>package data</dfn> algorithm, given
<var>bytes</var>, <var>type</var>, and a <var>mimeType</var>, switches on <var>type</var>, and runs
the associated steps:
<div algorithm>
<p id=concept-body-package-data>The <dfn id=concept-body-consume-body for=Body>consume body</dfn>
algorithm, given an object that includes {{Body}} <var>object</var> and an algorithm that takes a
<a for=/>byte sequence</a> and returns a JavaScript value or throws an exception
<var>convertBytesToJSValue</var>, runs these steps:

<dl class=switch>
<dt><i>ArrayBuffer</i>
<dd>
<p>Return a new {{ArrayBuffer}} whose contents are <var>bytes</var>.
<ol>
<li><p>If <var>object</var> is <a for=Body>unusable</a>, then return <a>a promise rejected with</a>
a {{TypeError}}.

<p class=note>Allocating an {{ArrayBuffer}} can throw a {{RangeError}}.
<li><p>Let <var>promise</var> be <a>a new promise</a>.

<dt><i>Blob</i>
<dd><p>Return a {{Blob}} whose contents are <var>bytes</var> and {{Blob/type}} attribute is
<var>mimeType</var>.
<li>Let <var>errorSteps</var> given <var>error</var> be to <a>reject</a> <var>promise</var> with
<var>error</var>.

<dt><i>FormData</i>
<dd>
<p>If <var>mimeType</var>'s <a for="MIME type">essence</a> is "<code>multipart/form-data</code>",
then:
<li>Let <var>successSteps</var> given a <a for=/>byte sequence</a> <var>data</var> be to
<a for=/>resolve</a> <var>promise</var> with the result of running <var>convertBytesToJSValue</var>
with <var>data</var>. If that threw an exception, then run <var>errorSteps</var> with that
exception.

<li><p>If <var>object</var>'s <a for=Body>body</a> is null, then run <var>successSteps</var>
with an empty <a for=/>byte sequence</a>.

<li><p>Otherwise, <a for=body>fully read</a> <var>object</var>'s <a for=Body>body</a> given
<var>successSteps</var>, <var>errorSteps</var>, and <var>object</var>'s
<a>relevant global object</a>.

<li><p>Return <var>promise</var>.
</ol>
</div>

<div algorithm>
<p>The <dfn method for=Body><code>arrayBuffer()</code></dfn> method steps are to return the result
of running <a for=Body>consume body</a> with <a>this</a> and the following step given a
<a for=/>byte sequence</a> <var>bytes</var>: return a new {{ArrayBuffer}} whose contents are
<var>bytes</var>.

<p class="note">The above method can reject with a {{RangeError}}.
</div>

<div algorithm>
<p>The <dfn method for=Body><code>blob()</code></dfn> method steps are to return the result
of running <a for=Body>consume body</a> with <a>this</a> and the following step given a
<a for=/>byte sequence</a> <var>bytes</var>: return a {{Blob}} whose contents are <var>bytes</var>
and whose {{Blob/type}} attribute is <a>this</a>'s <a for=Body>MIME type</a>.
</div>

<div algorithm>
<p>The <dfn method for=Body><code>formData()</code></dfn> method steps are to return the result of
running <a for=Body>consume body</a> with <a>this</a> and the following step given a
<a for=/>byte sequence</a> <var>bytes</var>: switch on <a>this</a>'s <a for=Body>MIME type</a>'s
<a for="MIME type">essence</a> and run the corresponding steps:

<dl class=switch>
<dt>"<code>multipart/form-data</code>",
<dd>
<ol>
<li>
<p>Parse <var>bytes</var>, using the value of the `<code>boundary</code>` parameter from
<var>mimeType</var>, per the rules set forth in
<a>this</a>'s <a for=Body>MIME type</a>, per the rules set forth in
<cite>Returning Values from Forms: multipart/form-data</cite>. [[!RFC7578]]</p>

<p>Each part whose `<code>Content-Disposition</code>` header contains a `<code>filename</code>`
Expand Down Expand Up @@ -6950,62 +6977,34 @@ the associated steps:
`<code>multipart/form-data</code>`, a more detailed parsing specification is to be
written. Volunteers welcome.

<p>Otherwise, if <var>mimeType</var>'s <a for="MIME type">essence</a> is
"<code>application/x-www-form-urlencoded</code>", then:

<dt>"<code>application/x-www-form-urlencoded</code>",
<dd>
<ol>
<li><p>Let <var>entries</var> be the result of
<a lt="urlencoded parser">parsing</a> <var>bytes</var>.
<li><p>Let <var>entries</var> be the result of <a lt="urlencoded parser">parsing</a>
<var>bytes</var>.

<li><p>If <var>entries</var> is failure, then <a>throw</a> a {{TypeError}}.

<li><p>Return a new {{FormData}} object whose <a for=FormData>entry list</a> is
<var>entries</var>.
</ol>

<p>Otherwise, <a>throw</a> a {{TypeError}}.

<dt><i>JSON</i>
<dd><p>Return the result of running <a>parse JSON from bytes</a> on <var>bytes</var>.

<dt><i>text</i>
<dd><p>Return the result of running <a>UTF-8 decode</a> on
<var>bytes</var>.
<dt>Otherwise
<dd><p><a>Throw</a> a {{TypeError}}.
</dl>
</div>

<p>The <dfn id=concept-body-consume-body for=Body>consume body</dfn> algorithm, given an
<var>object</var> and <var>type</var>, runs these steps:

<ol>
<li><p>If <var>object</var> is <a for=Body>unusable</a>, then return <a>a promise rejected with</a>
a {{TypeError}}.

<li><p>Let <var>promise</var> be <a>a promise resolved with</a> an empty
<a for=/>byte sequence</a>.

<li><p>If <var>object</var>'s <a for=Body>body</a> is non-null, then set <var>promise</var> to the
result of <a>fully reading body as promise</a> given <var>object</var>'s <a for=Body>body</a>.

<li><p>Let <var>steps</var> be to return the result of <a>package data</a> with the first argument
given, <var>type</var>, and <var>object</var>'s <a for=Body>MIME type</a>.

<li><p>Return the result of <a>upon fulfillment</a> of <var>promise</var> given <var>steps</var>.
</ol>

<p>The <dfn method for=Body><code>arrayBuffer()</code></dfn> method steps are to return the result
of running <a for=Body>consume body</a> with <a>this</a> and <i>ArrayBuffer</i>.

<p>The <dfn method for=Body><code>blob()</code></dfn> method steps are to return the result of
running <a for=Body>consume body</a> with <a>this</a> and <i>Blob</i>.

<p>The <dfn method for=Body><code>formData()</code></dfn> method steps are to return the result of
running <a for=Body>consume body</a> with <a>this</a> and <i>FormData</i>.
<div algorithm>
<p>The <dfn method for=Body><code>json()</code></dfn> method steps are to return the result
of running <a for=Body>consume body</a> with <a>this</a> and <a>parse JSON from bytes</a>.

<p>The <dfn method for=Body><code>json()</code></dfn> method steps are to return the result of
running <a for=Body>consume body</a> with <a>this</a> and <i>JSON</i>.
<p class="note">The above method can reject with a {{SyntaxError}}.
</div>

<p>The <dfn method for=Body><code>text()</code></dfn> method steps are to return the result of
running <a for=Body>consume body</a> with <a>this</a> and <i>text</i>.
<div algorithm>
<p>The <dfn method for=Body><code>text()</code></dfn> method steps are to return the result
of running <a for=Body>consume body</a> with <a>this</a> and <a>UTF-8 decode</a>.
</div>


<h3 id=request-class>Request class</h3>
Expand Down

0 comments on commit 464326e

Please sign in to comment.