@@ -1976,6 +1976,49 @@ See also:
1976
1976
1977
1977
* <a href="https://www.w3.org/2001/tag/doc/promises-guide">Writing Promise-Using Specifications</a>
1978
1978
1979
+ <h4 id="sync-callbacks" class="no-num no-toc">When to use callback functions</h4>
1980
+
1981
+ Use synchronous callbacks only when an immediate response is needed.
1982
+
1983
+ Synchronous actions are sometimes needed in APIs,
1984
+ particularly where there are latency-sensitive actions involved.
1985
+ For example, browsers need to know how to proceed immediately after an event finishes bubbling,
1986
+ and media processing can't always wait for the next task boundary.
1987
+ Synchronous actions cannot be modeled with a Promise.
1988
+ Instead, use an explicit callback or event.
1989
+
1990
+ In [Promise reaction callbacks] (https://tc39.es/ecma262/multipage/control-abstraction-objects.html#sec-promisereaction-records),
1991
+ you may not require action within
1992
+ a fixed number of microtasks.
1993
+
1994
+ This protects Promise composition: patterns like <code> await</code> ,
1995
+ wrapping helper functions, logging, <code> Promise.race()</code> , or multiple
1996
+ <code> .then()</code> branches all queue an extra microtask and must
1997
+ not significantly change the behavior of the code they wrap.
1998
+
1999
+ <div class=example>
2000
+
2001
+ Event handlers are invoked and cancelled synchronously.
2002
+ If developer-supplied code needs to be able to call <code> event.{{Event/preventDefault()}} </code>
2003
+ or choose a response object with
2004
+ <code> fetchEvent.{{FetchEvent/respondWith()}} </code> ,
2005
+ it needs to be a callback rather than a reaction passed to <code> Promise.{{Promise/then()}} </code> .
2006
+
2007
+ </div>
2008
+ <div class="example">
2009
+
2010
+ A non-event example is the <code> captureController.{{CaptureController/setFocusBehavior()}} </code>
2011
+ method, which pushes a window the user has chosen to screen-capture to
2012
+ the front. Applications can decide this based on the window chosen.
2013
+ The challenge is that allowing delay creates an opportunity for click-jacking attacks from sites.
2014
+
2015
+ Instead of requiring the method be called synchronously on the
2016
+ reaction microtask of the promise from {{getDisplayMedia()}} , the
2017
+ solution was to instead require the method be called on the
2018
+ same promise reaction task, with a one second timeout.
2019
+
2020
+ </div>
2021
+
1979
2022
<h3 id="aborting">Cancel asynchronous APIs/operations using AbortSignal</h3>
1980
2023
1981
2024
If an asynchronous method can be cancelled,
@@ -2142,6 +2185,10 @@ Follow the <a href="https://www.w3.org/2001/tag/doc/promises-guide#one-time-even
2142
2185
in the <strong> <a href="https://www.w3.org/2001/tag/doc/promises-guide">Writing
2143
2186
Promise-Using Specifications</a> </strong> guideline.
2144
2187
2188
+ <h3 id="promises-and-reaction">Don't use promises for cancelable events</h3>
2189
+
2190
+ See <a href="#sync-callbacks">when to use callback functions instead</a> .
2191
+
2145
2192
<h3 id="promises-and-events">Events should fire before related Promises resolve</h3>
2146
2193
2147
2194
If a Promise-based asynchronous algorithm dispatches events,
0 commit comments