@@ -30,6 +30,7 @@ type: interface
3030urlPrefix: https://tc39.es/ecma262/#; spec: ECMASCRIPT
3131 text: Construct; url: sec-construct; type: abstract-op
3232 type: dfn
33+ text: current realm; url: current-realm
3334 text: realm; url: realm
3435 text: surrounding agent; url: surrounding-agent
3536urlPrefix: https://w3c.github.io/hr-time/#; spec: HR-TIME
@@ -1768,6 +1769,7 @@ interface AbortController {
17681769<p> An {{AbortController}} object has an associated <dfn for=AbortController>signal</dfn> (an
17691770{{AbortSignal}} object).
17701771
1772+ <div algorithm>
17711773<p> The
17721774<dfn constructor for=AbortController lt="AbortController()"><code>new AbortController()</code></dfn>
17731775constructor steps are:
@@ -1777,13 +1779,22 @@ constructor steps are:
17771779
17781780 <li><p> Set <a>this</a> 's <a for=AbortController>signal</a> to <var> signal</var> .
17791781</ol>
1782+ </div>
17801783
17811784<p> The <dfn attribute for=AbortController><code>signal</code></dfn> getter steps are to return
17821785<a>this</a> 's <a for=AbortController>signal</a> .
17831786
1787+ <div algorithm>
17841788<p> The <dfn method for=AbortController><code>abort(<var>reason</var>)</code></dfn> method steps are
1785- to <a for=AbortSignal>signal abort</a> on <a>this</a> 's <a for=AbortController>signal</a> with
1786- <var> reason</var> if it is given.
1789+ to <a for=AbortController>signal abort</a> on <a>this</a> with <var> reason</var> if it is given.
1790+ </div>
1791+
1792+ <div algorithm>
1793+ <p> To <dfn export for=AbortController>signal abort</dfn> on an {{AbortController}}
1794+ <var> controller</var> with an optional <var> reason</var> , <a for=AbortSignal>signal abort</a> on
1795+ <var> controller</var> 's <a for=AbortController>signal</a> with <var> reason</var> if it is given.
1796+ </div>
1797+
17871798
17881799<h3 id=interface-AbortSignal>Interface {{AbortSignal}}</h3>
17891800
@@ -1792,6 +1803,7 @@ to <a for=AbortSignal>signal abort</a> on <a>this</a>'s <a for=AbortController>s
17921803interface AbortSignal : EventTarget {
17931804 [NewObject] static AbortSignal abort(optional any reason);
17941805 [Exposed=(Window,Worker), NewObject] static AbortSignal timeout([EnforceRange] unsigned long long milliseconds);
1806+ [NewObject] static AbortSignal _any(sequence<AbortSignal> signals);
17951807
17961808 readonly attribute boolean aborted;
17971809 readonly attribute any reason;
@@ -1805,6 +1817,11 @@ interface AbortSignal : EventTarget {
18051817 <dd> Returns an {{AbortSignal}} instance whose <a for=AbortSignal>abort reason</a> is set to
18061818 <var> reason</var> if not undefined; otherwise to an "{{AbortError!!exception}} " {{DOMException}} .
18071819
1820+ <dt><code> AbortSignal . <a method for=AbortSignal lt=any(signals)>any</a> (<var> signals</var> )</code>
1821+ <dd> Returns an {{AbortSignal}} instance which will be aborted once any of <var> signals</var> is
1822+ aborted. Its <a for=AbortSignal>abort reason</a> will be set to whichever one of <var> signals</var>
1823+ caused it to be aborted.
1824+
18081825 <dt><code> AbortSignal . <a method for=AbortSignal lt=timeout(milliseconds)>timeout</a> (<var> milliseconds</var> )</code>
18091826 <dd> Returns an {{AbortSignal}} instance which will be aborted in <var> milliseconds</var>
18101827 milliseconds. Its <a for=AbortSignal>abort reason</a> will be set to a
@@ -1821,35 +1838,32 @@ interface AbortSignal : EventTarget {
18211838 {{AbortController}} has signaled to abort; otherwise, does nothing.
18221839</dl>
18231840
1824- <p> An {{AbortSignal}} object has an associated <dfn export for=AbortSignal>abort reason</dfn> , which is a
1825- JavaScript value. It is undefined unless specified otherwise.
1826-
1827- <p> An {{AbortSignal}} object is <dfn export for="AbortSignal">aborted</dfn> when its
1828- [=AbortSignal/abort reason=] is not undefined.
1829-
1830- <p> An {{AbortSignal}} object has associated <dfn for=AbortSignal>abort algorithms</dfn> , which is a
1831- <a for=/>set</a> of algorithms which are to be executed when it is [=AbortSignal/aborted=] . Unless
1832- specified otherwise, its value is the empty set.
1833-
1834- <p> To <dfn export for=AbortSignal>add</dfn> an algorithm <var> algorithm</var> to an {{AbortSignal}}
1835- object <var> signal</var> , run these steps:
1836-
1837- <ol>
1838- <li><p> If <var> signal</var> is [=AbortSignal/aborted=] , then return.
1839-
1840- <li><p> <a for=set>Append</a> <var> algorithm</var> to <var> signal</var> 's
1841- <a for=AbortSignal>abort algorithms</a> .
1842- </ol>
1841+ <p> An {{AbortSignal}} object has an associated <dfn export for=AbortSignal>abort reason</dfn> (a
1842+ JavaScript value), which is initially undefined.
18431843
1844- <p> To <dfn export for=AbortSignal>remove </dfn> an algorithm <var> algorithm </var> from an
1845- {{AbortSignal}} <var> signal </var> , < a for=set>remove </a> <var> algorithm </var> from
1846- <var> signal </var> 's <a for=AbortSignal>abort algorithms</a> .
1844+ <p> An {{AbortSignal}} object has associated <dfn for=AbortSignal>abort algorithms </dfn> , (a
1845+ < a for=/>set </a> of algorithms which are to be executed when it is [=AbortSignal/aborted=] ),
1846+ which is initially empty .
18471847
18481848<p class=note> The [=AbortSignal/abort algorithms=] enable APIs with complex
18491849requirements to react in a reasonable way to {{AbortController/abort()}} . For example, a given API's
18501850[=AbortSignal/abort reason=] might need to be propagated to a cross-thread environment, such as a
18511851service worker.
18521852
1853+ <p> An {{AbortSignal}} object has a <dfn for="AbortSignal">dependent</dfn> (a boolean), which is
1854+ initially false.
1855+
1856+ <p> An {{AbortSignal}} object has associated <dfn for=AbortSignal>source signals</dfn> (a weak
1857+ <a for=/>set</a> of {{AbortSignal}} objects that the object is dependent on for its
1858+ [=AbortSignal/aborted=] state), which is initially empty.
1859+
1860+ <p> An {{AbortSignal}} object has associated <dfn for=AbortSignal>dependent signals</dfn> (a weak
1861+ <a for=/>set</a> of {{AbortSignal}} objects that are dependent on the object for their
1862+ [=AbortSignal/aborted=] state), which is initially empty.
1863+
1864+ <hr>
1865+
1866+ <div algorithm>
18531867<p> The static <dfn method for=AbortSignal><code>abort(<var>reason</var>)</code></dfn> method steps
18541868are:
18551869
@@ -1861,7 +1875,9 @@ are:
18611875
18621876 <li> Return <var> signal</var> .
18631877</ol>
1878+ </div>
18641879
1880+ <div algorithm>
18651881<p> The static <dfn method for=AbortSignal><code>timeout(<var>milliseconds</var>)</code></dfn> method
18661882steps are:
18671883
@@ -1886,6 +1902,13 @@ steps are:
18861902
18871903 <li><p> Return <var> signal</var> .
18881904</ol>
1905+ </div>
1906+
1907+ <div algorithm>
1908+ <p> The static <dfn method for=AbortSignal><code>any(<var>signals</var>)</code></dfn> method
1909+ steps are to return the result of <a>creating a dependent abort signal</a> from <var> signals</var>
1910+ using {{AbortSignal}} and the <a>current realm</a> .
1911+ </div>
18891912
18901913<p> The <dfn attribute for=AbortSignal>aborted</dfn> getter steps are to return true if <a>this</a>
18911914is [=AbortSignal/aborted=] ; otherwise false.
@@ -1924,46 +1947,114 @@ is [=AbortSignal/aborted=]; otherwise false.
19241947<dfn event for=AbortSignal><code>abort</code></dfn> .
19251948
19261949<p class=note> Changes to an {{AbortSignal}} object represent the wishes of the corresponding
1927- {{AbortController}} object, but an API observing the {{AbortSignal}} object can chose to ignore
1950+ {{AbortController}} object, but an API observing the {{AbortSignal}} object can choose to ignore
19281951them. For instance, if the operation has already completed.
19291952
1953+ <hr>
1954+
1955+ <p> An {{AbortSignal}} object is <dfn export for="AbortSignal">aborted</dfn> when its
1956+ [=AbortSignal/abort reason=] is not undefined.
1957+
1958+ <div algorithm>
1959+ <p> To <dfn export for=AbortSignal>add</dfn> an algorithm <var> algorithm</var> to an {{AbortSignal}}
1960+ object <var> signal</var> :
1961+
1962+ <ol>
1963+ <li><p> If <var> signal</var> is [=AbortSignal/aborted=] , then return.
1964+
1965+ <li><p> <a for=set>Append</a> <var> algorithm</var> to <var> signal</var> 's
1966+ <a for=AbortSignal>abort algorithms</a> .
1967+ </ol>
1968+ </div>
1969+
1970+ <div algorithm>
1971+ <p> To <dfn export for=AbortSignal>remove</dfn> an algorithm <var> algorithm</var> from an
1972+ {{AbortSignal}} <var> signal</var> , <a for=set>remove</a> <var> algorithm</var> from
1973+ <var> signal</var> 's <a for=AbortSignal>abort algorithms</a> .
1974+ </div>
1975+
1976+ <div algorithm>
19301977<p> To <dfn export for=AbortSignal>signal abort</dfn> , given an {{AbortSignal}} object
1931- <var> signal</var> and an optional <var> reason</var> , run these steps :
1978+ <var> signal</var> and an optional <var> reason</var> :
19321979
19331980<ol>
19341981 <li><p> If <var> signal</var> is [=AbortSignal/aborted=] , then return.
19351982
19361983 <li><p> Set <var> signal</var> 's [=AbortSignal/abort reason=] to <var> reason</var> if it is given;
19371984 otherwise to a new "{{AbortError!!exception}} " {{DOMException}} .
19381985
1939- <li><p> <a for=set>For each</a> <var> algorithm</var> in <var> signal</var> 's
1986+ <li><p> <a for=set>For each</a> <var> algorithm</var> of <var> signal</var> 's
19401987 [=AbortSignal/abort algorithms=] : run <var> algorithm</var> .
19411988
19421989 <li><p> <a for=set>Empty</a> <var> signal</var> 's <a for=AbortSignal>abort algorithms</a> .
19431990
19441991 <li><p> [=Fire an event=] named {{AbortSignal/abort}} at <var> signal</var> .
1992+
1993+ <li><p> <a for=set>For each</a> <var> dependentSignal</var> of <var> signal</var> 's
1994+ [=AbortSignal/dependent signals=] , [=AbortSignal/signal abort=] on <var> dependentSignal</var> with
1995+ <var> signal</var> 's [=AbortSignal/abort reason=] .
19451996</ol>
1997+ </div>
19461998
1947- <p> A <var> followingSignal</var> (an {{AbortSignal}} ) is made to
1948- <dfn export for=AbortSignal>follow</dfn> a <var> parentSignal</var> (an {{AbortSignal}} ) by running
1949- these steps:
1999+ <div algorithm>
2000+ <p> To <dfn export>create a dependent abort signal</dfn> from a list of {{AbortSignal}} objects
2001+ <var> signals</var> , using <var> signalInterface</var> , which must be either {{AbortSignal}} or an
2002+ interface that inherits from it, and a <var> realm</var> :
19502003
19512004<ol>
1952- <li><p> If <var> followingSignal</var> is [=AbortSignal/aborted=] , then return.
2005+ <li><p> Let <var> resultSignal</var> be a <a for=/>new</a> object implementing
2006+ <var> signalInterface</var> using <var> realm</var> .
19532007
1954- <li><p> If <var> parentSignal</var> is [=AbortSignal/aborted=] , then
1955- <a for=AbortSignal>signal abort</a> on <var> followingSignal</var> with <var> parentSignal</var> 's
1956- [=AbortSignal/abort reason=] .
2008+ <li><p> <a for=list>For each</a> <var> signal</var> of <var> signals</var> : if <var> signal</var> is
2009+ [=AbortSignal/aborted=] , then set <var> resultSignal</var> 's [=AbortSignal/abort reason=] to
2010+ <var> signal</var> 's [=AbortSignal/abort reason=] and return <var> resultSignal</var> .
2011+
2012+ <li><p> Set <var> resultSignal</var> 's [=AbortSignal/dependent=] to true.
19572013
19582014 <li>
1959- <p> Otherwise, <a for=AbortSignal lt=add>add the following abort steps</a> to
1960- <var> parentSignal</var> :
2015+ <p> <a for=list>For each</a> <var> signal</var> of <var> signals</var> :
19612016
19622017 <ol>
1963- <li><p> <a for=AbortSignal>Signal abort</a> on <var> followingSignal</var> with
1964- <var> parentSignal</var> 's [=AbortSignal/abort reason=] .
2018+ <li>
2019+ <p> If <var> signal</var> 's [=AbortSignal/dependent=] is false, then:
2020+
2021+ <ol>
2022+ <li><p> <a for=set>Append</a> <var> signal</var> to <var> resultSignal</var> 's
2023+ [=AbortSignal/source signals=] .
2024+
2025+ <li><p> <a for=set>Append</a> <var> resultSignal</var> to <var> signal</var> 's
2026+ [=AbortSignal/dependent signals=] .
2027+ </ol>
2028+
2029+ <li>
2030+ <p> Otherwise, <a for=list>for each</a> <var> sourceSignal</var> of <var> signal</var> 's
2031+ [=AbortSignal/source signals=] :
2032+
2033+ <ol>
2034+ <li><p> Assert: <var> sourceSignal</var> is not [=AbortSignal/aborted=] and not
2035+ [=AbortSignal/dependent=] .
2036+
2037+ <li><p> If <var> resultSignal</var> 's [=AbortSignal/source signals=] <a for=set>contains</a>
2038+ <var> sourceSignal</var> , then <a for=iteration>continue</a> .
2039+
2040+ <li><p> <a for=set>Append</a> <var> sourceSignal</var> to <var> resultSignal</var> 's
2041+ [=AbortSignal/source signals=] .
2042+
2043+ <li><p> <a for=set>Append</a> <var> resultSignal</var> to <var> sourceSignal</var> 's
2044+ [=AbortSignal/dependent signals=] .
2045+ </ol>
19652046 </ol>
2047+
2048+ <li><p> Return <var> resultSignal</var> .
19662049</ol>
2050+ </div>
2051+
2052+
2053+ <h4 id=abort-signal-garbage-collection>Garbage collection</h4>
2054+
2055+ <p> A non-[=AbortSignal/aborted=] [=AbortSignal/dependent=] {{AbortSignal}} object must not be
2056+ garbage collected while its [=AbortSignal/source signals=] is non-empty and it has registered event
2057+ listeners for its {{AbortSignal/abort}} event or its [=AbortSignal/abort algorithms=] is non-empty.
19672058
19682059
19692060<h3 id=abortcontroller-api-integration>Using {{AbortController}} and {{AbortSignal}} objects in
0 commit comments