Skip to content

Commit 625897d

Browse files
noamrdomenicannevkjyasskin
committed
Editorial: rework callbacks & controller howto
Instead of describing the callbacks one by one, put emphasis on how/when the caller expects responses (upon completion, chunk-by-chunk, fire-and-forget). This (hopefully) gives other specs who need to call into Fetch a quick reference between what they're trying to do and the API. Co-Authored-By: Domenic Denicola <[email protected]> Co-Authored-By: Anne van Kesteren <[email protected]> Co-Authored-By: Jeffrey Yasskin <[email protected]>
1 parent aaada1f commit 625897d

File tree

1 file changed

+127
-50
lines changed

1 file changed

+127
-50
lines changed

fetch.bs

+127-50
Original file line numberDiff line numberDiff line change
@@ -8769,53 +8769,28 @@ relevant to you. The rest of the parameters are used less frequently, often for
87698769
and they are documented in detail in the [[#requests]] section of this standard.
87708770

87718771

8772-
<h3 id=fetch-elsewhere-fetch class=no-num>Invoking fetch</h3>
8772+
<h3 id=fetch-elsewhere-fetch class=no-num>Invoking fetch and processing responses</h3>
87738773

87748774
<p>Aside from a <a for=/>request</a> the <a for=/>fetch</a> operation takes several optional
87758775
arguments. For those arguments that take an algorithm: the algorithm will be called from a task (or
87768776
in a <a for=/>parallel queue</a> if <a for=fetch><i>useParallelQueue</i></a> is true).
87778777

8778-
<dl>
8779-
<dt><a for=fetch><i>processRequestBodyChunkLength</i></a>
8780-
<dd><p>Takes an algorithm that will be passed the number of bytes that have been transmitted from
8781-
the <a for=/>request</a>'s <a for=request>body</a>. The algorithm will be invoked for each
8782-
transmitted chunk. Most standards will not need this.
8783-
8784-
<dt><a for=fetch><i>processRequestEndOfBody</i></a>
8785-
<dd><p>Takes an algorithm that will be passed nothing. Indicates <a for=/>request</a>'s
8786-
<a for=request>body</a> has been transmitted. Most standards will not need this.
8787-
8788-
<dt><a for=fetch><i>processEarlyHintsResponse</i></a>
8789-
<dd><p>Takes an algorithm that will be passed a <a for=/>response</a> (whose
8790-
<a for=response>status</a> is 103). Can only be used for navigations as defined by
8791-
<cite>HTML</cite>. [[HTML]]
8778+
<p>Once the <a for=/>request</a> is set up, to determine which algorithms to pass to
8779+
<a for=/>fetch</a>, determine how you would like to process the <a for=/>response</a>, and in
8780+
particular at what stage you would like to receive a callback:
87928781

8793-
<dt><a for=fetch><i>processResponse</i></a>
8782+
<dl>
8783+
<dt>Upon completion
87948784
<dd>
8795-
<p>Takes an algorithm that will be passed a <a for=/>response</a>. Indicates
8796-
<a for=/>response</a>'s <a for=response>header list</a> has been received and initialized. This
8797-
is primarily useful for standards that want to operate on <a for=/>response</a>'s
8798-
<a for=response>body</a>'s <a for=body>stream</a> directly.
8799-
8800-
<p>If the <a for=/>request</a>'s <a for=request>mode</a> is "<code>navigate</code>" and its
8801-
<a for=request>redirect mode</a> is "<code>manual</code>", then callers need to follow a very
8802-
specific flow with this algorithm to get the intended behavior. They should compute the
8803-
appropriate <a for=response>location URL</a>, and if it is non-null or failure, then they should
8804-
call <a for="fetch controller">process the next manual redirect</a>. This will result in
8805-
<a for=fetch><i>processResponse</i></a> being called again, with the next <a for=/>response</a>
8806-
in the redirect chain.
8807-
8808-
<dt><a for=fetch><i>processResponseEndOfBody</i></a>
8809-
<dd><p>Takes an algorithm that will be passed a <a for=/>response</a>. Indicates the network is
8810-
done transmitting the response. This does not read <a for=/>response</a>'s
8811-
<a for=response>body</a>.
8785+
<p>This is how most callers handle a <a for=/>response</a>, for example
8786+
<a lt="fetch a classic script">scripts</a> and <a lt="fetch a style resource">style resources</a>.
8787+
The <a for=/>response</a>'s <a for=response>body</a> is read in its entirety into a
8788+
<a>byte sequence</a>, and then processed by the caller.
88128789

8813-
<dt><a for=fetch><i>processResponseConsumeBody</i></a>
8814-
<dd>
8815-
<p>Takes an algorithm that will be passed a <a for=/>response</a> and null, failure, or a
8816-
<a>byte sequence</a>. This is useful for standards that wish to operate on the entire
8817-
<a for=/>response</a>'s <a for=response>body</a>, of which the result of reading it is supplied as
8818-
second argument. The second argument's values have the following meaning:
8790+
<p>To process a <a for=/>response</a> upon completion, pass an algorithm as the
8791+
<a for=fetch><i>processResponseConsumeBody</i></a> argument of <a for=/>fetch</a>. The given
8792+
algorithm is passed a <a for=/>response</a> and an argument representing the fully read
8793+
<a for=response>body</a>. The second argument's values have the following meaning:
88198794

88208795
<dl>
88218796
<dt>null
@@ -8831,20 +8806,122 @@ in a <a for=/>parallel queue</a> if <a for=fetch><i>useParallelQueue</i></a> is
88318806
<a for=response>body</a> succeeded.
88328807
</dl>
88338808

8834-
<p class=warning>A standard that uses this argument cannot operate on <a for=/>response</a>'s
8835-
<a for=response>body</a> itself as providing this argument will cause it to be read and it can be
8836-
read only once.
8809+
<div id=example-callback-upon-completion class=example>
8810+
<ol>
8811+
<li><p>Let <var>request</var> be a <a for=/>request</a> whose <a for=request>URL</a> is
8812+
<code>https://stuff.example.com/</code> and <a for=request>client</a> is <a>this</a>'s
8813+
<a>relevant settings object</a>.
8814+
8815+
<li>
8816+
<p><a for=/>Fetch</a> <var>request</var>, with
8817+
<a for=fetch><i>processResponseConsumeBody</i></a> set to the following steps given
8818+
a <a for=/>response</a> <var>response</var> and null, failure, or a <a>byte sequence</a>
8819+
<var>contents</var>:
8820+
8821+
<ol>
8822+
<li><p>If <var>contents</var> is null or failure, then present an error to the user.
8823+
8824+
<li><p>Otherwise, parse <var>contents</var> considering the metadata from <var>response</var>,
8825+
and perform your own operations on it.
8826+
</ol>
8827+
</li>
8828+
</div>
8829+
</dd>
88378830

8838-
<dt><a for=fetch><i>useParallelQueue</i></a>
8839-
<dd><p>Takes a <a for=/>boolean</a> that defaults to false. Indicates where the algorithms passed
8840-
as arguments will be invoked. Hopefully most standards will not need this.
8841-
</dl>
8831+
<dt>Headers first, then chunk-by-chunk
8832+
<dd>
8833+
<p>In some cases, for example when playing video or progressively loading images, callers might
8834+
want to stream the response, and process it one chunk at a time. The <a for=/>response</a> is
8835+
handed over to the fetch caller once the headers are processed, and the caller
8836+
continues from there.
8837+
8838+
<p>To process a <a for=/>response</a> chunk-by-chunk, pass an algorithm to the
8839+
<a for=fetch><i>processResponse</i></a> argument of <a for/>fetch</a>. The given
8840+
algorithm is passed a <a for=/>response</a> when the response's headers have been
8841+
received and is responsible for reading the <a for=/>response</a>'s
8842+
<a for=response>body</a>'s <a for=body>stream</a> in order to download the rest
8843+
of the response. For convenience, you may also pass an algorithm to the
8844+
<a for=fetch><i>processResponseEndOfBody</i></a> argument, which is called once you have finished
8845+
fully reading the response and its <a for=response>body</a>. Note that unlike
8846+
<a for=fetch><i>processResponseConsumeBody</i></a>, passing the
8847+
<a for=fetch><i>processResponse</i></a> or <a for=fetch><i>processResponseEndOfBody</i></a> arguments
8848+
does not guarantee that the response will be fully read, and callers are responsible to
8849+
read it themselves.
8850+
8851+
<p>The <a for=fetch><i>processResponse</i></a> argument is also useful for handling the
8852+
<a for=/>response</a>'s <a for=response>header list</a> and <a for=response>status</a> without
8853+
handling the <a for=response>body</a> at all. This is used, for example, when handling responses
8854+
that do not have an <a for=/>ok status</a>.
8855+
8856+
<div id=example-callback-chunk-by-chunk class=example>
8857+
<ol>
8858+
<li><p>Let <var>request</var> be a <a for=/>request</a> whose <a for=request>URL</a> is
8859+
<code>https://stream.example.com/</code> and <a for=request>client</a> is <a>this</a>'s
8860+
<a>relevant settings object</a>.
8861+
8862+
<li>
8863+
<p><a for=/>Fetch</a> <var>request</var>, with
8864+
<a for=fetch><i>processResponse</i></a> set to the following steps given a
8865+
<a for=/>response</a> <var>response</var>:
8866+
8867+
<ol>
8868+
<li><p>If <var>response</var> is a <a>network error</a>, then present an error to the user.
8869+
8870+
<li><p>Otherwise, if <var>response</var>'s <a for=response>status</a> is not an
8871+
<a>ok status</a>, present some fallback value to the user.
8872+
8873+
<li><p>Otherwise, <a for=ReadableStream>get a reader</a> for <a for=/>response</a>'s
8874+
<a for=response>body</a>'s <a for=body>stream</a>, and process in an appropriate way for the
8875+
MIME type identified by <a>extracting a MIME type</a> from <var>response</var>'s <a for=response>headers list</a>.
8876+
</ol>
8877+
</li>
8878+
</div>
8879+
</dd>
88428880

8843-
<p>When invoked, the <a for=/>fetch</a> operation returns a <a for=/>fetch controller</a>. The
8844-
controller is used for performing actions on a fetch operation that has already started, such as
8845-
<a for="fetch controller" lt=abort>aborting</a> the operation by the user or page logic, or
8846-
<a for="fetch controller" lt=terminate>terminating</a> it due to a browser-internal circumstance.
8881+
<dt>Ignore the response
8882+
<dd>
8883+
<p>In some cases, there is no need for a <a for=/>response</a> at all, e.g., in the case of
8884+
{{Navigator/sendBeacon()|navigator.sendBeacon()}}. Processing a response and passing callbacks to
8885+
<a for=/>fetch</a> is optional, so omitting the callback would <a for=/>fetch</a> without
8886+
expecting a response. In such cases, the <a for=/>response</a>'s <a for=response>body</a>'s
8887+
<a for=body>stream</a> will be discarded, and the caller does not have to worry about downloading
8888+
the contents unnecessarily.
8889+
8890+
<p id=example-no-callback class=example><a for=/>Fetch</a> a <a for=/>request</a> whose
8891+
<a for=request>URL</a> is <code>https://fire-and-forget.example.com/</code>,
8892+
<a for=request>method</a> is `<code>POST</code>`, and <a for=request>client</a> is <a>this</a>'s
8893+
<a>relevant settings object</a>.
8894+
</dd>
8895+
</dl>
88478896

8897+
<p>Apart from the callbacks to handle responses, <a for=/>fetch</a> accepts additional callbacks
8898+
for advanced cases. <a for=fetch><i>processEarlyHintsResponse</i></a> is intended specifically for
8899+
<a for=/>responses</a> whose <a for=response>status</a> is 103, and is currently handled only by
8900+
navigations. <a for=fetch><i>processRequestBodyChunkLength</i></a> and
8901+
<a for=fetch><i>processRequestEndOfBody</i></a> notify the caller of request body uploading
8902+
progress.
8903+
8904+
<p>Note that the <a for=/>fetch</a> operation starts in the same thread from which it was called,
8905+
and then breaks off to run its internal operations <a>in parallel</a>. The aforementioned callbacks
8906+
are posted to a given <a for=/>event loop</a> which is, by default, the
8907+
<a for=request>client</a>'s <a for="environment settings object">global object</a>. To process
8908+
responses <a>in parallel</a> and handle interactions with the main thread by yourself,
8909+
<a for=/>fetch</a> with <a for=fetch><i>useParallelQueue</i></a> set to true.
8910+
8911+
8912+
<h3 id=fetch-elsewhere-ongoing>Manipulating an ongoing fetch</h3>
8913+
8914+
<p>To manipulate a <a for=/>fetch</a> operation that has already started, use the
8915+
<a for=/>fetch controller</a> returned by calling <a for=/>fetch</a>. For example, you may
8916+
<a for="fetch controller">abort</a> the <a>fetch controller</a> due the user or page logic, or
8917+
<a for="fetch controller">terminate</a> it due to browser-internal circumstances.
8918+
8919+
<p>In addition to terminating and aborting, callers may <a for="fetch controller">report timing</a>
8920+
if this was not done automatically by passing the <a for=request>initiator type</a>, or
8921+
<a for="fetch controller">extract full timing info</a> and handle it on the caller side (this is
8922+
done only by navigations). The <a>fetch controller</a> is also used to
8923+
<a for="fetch controller">process the next manual redirect</a> for <a for=/>requests</a> with
8924+
<a for=request>redirect mode</a> set to "<code>manual</code>".
88488925

88498926

88508927
<h2 id=acknowledgments class=no-num>Acknowledgments</h2>

0 commit comments

Comments
 (0)