Section 1: An interesting thing…
A very interesting thing happened on the way to the forum…
# AbortController Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2019. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `AbortController` interface represents a controller object that allows you to abort one or more Web requests as and when desired. You can create a new `AbortController` object using the `AbortController()` constructor. Communicating with an asynchronous operation is done using an `AbortSignal` object. ## Constructor `AbortController()` Creates a new `AbortController` object instance. ## Instance properties `AbortController.signal` Read only Returns an `AbortSignal` object instance, which can be used to communicate with, or to abort, an asynchronous operation. ## Instance methods `AbortController.abort()` Aborts an asynchronous operation before it has completed. This is able to abort fetch requests, consumption of any response bodies, and streams. ## Examples **Note:** There are additional examples in the `AbortSignal` reference. In the following snippet, we aim to download a video using the Fetch API. We first create a controller using the `AbortController()` constructor, then grab a reference to its associated `AbortSignal` object using the `AbortController.signal` property. When the fetch request is initiated, we pass in the `AbortSignal` as an option inside the request's options object (the `{signal}` below). This associates the signal and controller with the fetch request and allows us to abort it by calling `AbortController.abort()`, as seen below in the second event listener. When `abort()` is called, the `fetch()` promise rejects with a `DOMException` named `AbortError`. let controller; const url = "video.mp4"; const downloadBtn = document.querySelector(".download"); const abortBtn = document.querySelector(".abort"); downloadBtn.addEventListener("click", fetchVideo); abortBtn.addEventListener("click", () => { if (controller) { controller.abort(); console.log("Download aborted"); } }); async function fetchVideo() { controller = new AbortController(); const signal = controller.signal; try { const response = await fetch(url, { signal }); console.log("Download complete", response); // process response further } catch (err) { console.error(`Download error: ${err.message}`); } } If the request is aborted after the `fetch()` call has been fulfilled but before the response body has been read, then attempting to read the response body will reject with an `AbortError` exception. async function get() { const controller = new AbortController(); const request = new Request("https://example.org/get", { signal: controller.signal, }); const response = await fetch(request); controller.abort(); // The next line will throw `AbortError` const text = await response.text(); console.log(text); } You can find a full working example on GitHub; you can also see it running live. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `AbortController` | 66 | 16 | 57 | 53 | 12.111.1–12.1Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 66 | 57 | 47 | 12.211.3–12.2Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 9.0 | 66 `AbortController` | 66 | 16 | 57 | 53 | 12.111.1–12.1Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 66 | 57 | 47 | 12.211.3–12.2Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 9.0 | 66 `abort` | 66 | 16 | 57 | 53 | 12.111.1–12.1Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 66 | 57 | 47 | 12.211.3–12.2Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 9.0 | 66 `signal` | 66 | 16 | 57 | 53 | 12.111.1–12.1Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 66 | 57 | 47 | 12.211.3–12.2Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 9.0 | 66 ## See also * Fetch API * Abortable Fetch by Jake Archibald # AbortController: abort() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2019. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `abort()` method of the `AbortController` interface aborts an asynchronous operation before it has completed. This is able to abort fetch requests, the consumption of any response bodies, or streams. ## Syntax abort() abort(reason) ### Parameters `reason` Optional The reason why the operation was aborted, which can be any JavaScript value. If not specified, the reason is set to "AbortError" `DOMException`. ### Return value None (`undefined`). ## Examples In the following snippet, we aim to download a video using the Fetch API. We first create a controller using the `AbortController()` constructor, then grab a reference to its associated `AbortSignal` object using the `AbortController.signal` property. When the fetch request is initiated, we pass in the `AbortSignal` as an option inside the request's options object (the `{signal}` below). This associates the signal and controller with the fetch request and allows us to abort it by calling `AbortController.abort()`, as seen below in the second event listener. const controller = new AbortController(); const signal = controller.signal; const url = "video.mp4"; const downloadBtn = document.querySelector(".download"); const abortBtn = document.querySelector(".abort"); downloadBtn.addEventListener("click", fetchVideo); abortBtn.addEventListener("click", () => { controller.abort(); console.log("Download aborted"); }); function fetchVideo() { fetch(url, { signal }) .then((response) => { console.log("Download complete", response); }) .catch((err) => { console.error(`Download error: ${err.message}`); }); } **Note:** When `abort()` is called, the `fetch()` promise rejects with an `Error` of type `DOMException`, with name `AbortError`. You can find a full working example on GitHub; you can also see it running live. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `abort` | 66 | 16 | 57 | 53 | 12.111.1–12.1Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 66 | 57 | 47 | 12.211.3–12.2Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 9.0 | 66 `reason_parameter` | 98 | 98 | 97 | 84 | 15.4 | 98 | 97 | 68 | 15.4 | 18.0 | 98 ## See also * Fetch API # AbortController: AbortController() constructor Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2019. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `AbortController()` constructor creates a new `AbortController` object instance. ## Syntax new AbortController() ### Parameters None. ## Examples In the following snippet, we aim to download a video using the Fetch API. We first create a controller using the `AbortController()` constructor, then grab a reference to its associated `AbortSignal` object using the `AbortController.signal` property. When the fetch request is initiated, we pass in the `AbortSignal` as an option inside the request's options object (the `{ signal }` below). This associates the signal and controller with the fetch request and allows us to abort it by calling `AbortController.abort()`, as seen below in the second event listener. const controller = new AbortController(); const signal = controller.signal; const url = "video.mp4"; const downloadBtn = document.querySelector(".download"); const abortBtn = document.querySelector(".abort"); downloadBtn.addEventListener("click", fetchVideo); abortBtn.addEventListener("click", () => { controller.abort(); console.log("Download aborted"); }); function fetchVideo() { fetch(url, { signal }) .then((response) => { console.log("Download complete", response); }) .catch((err) => { console.error(`Download error: ${err.message}`); }); } **Note:** When `abort()` is called, the `fetch()` promise rejects with an `AbortError`. You can find a full working example on GitHub; you can also see it running live. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `AbortController` | 66 | 16 | 57 | 53 | 12.111.1–12.1Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 66 | 57 | 47 | 12.211.3–12.2Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 9.0 | 66 ## See also * Fetch API # AbortController: signal property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2019. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `signal` read-only property of the `AbortController` interface returns an `AbortSignal` object instance, which can be used to communicate with/abort an asynchronous operation as desired. ## Value An `AbortSignal` object instance. ## Examples In the following snippet, we aim to download a video using the Fetch API. We first create a controller using the `AbortController()` constructor, then grab a reference to its associated `AbortSignal` object using the `AbortController.signal` property. When the fetch request is initiated, we pass in the `AbortSignal` as an option inside the request's options object (the `{signal}` below). This associates the signal and controller with the fetch request and allows us to abort it by calling `AbortController.abort()`, as seen below in the second event listener. const controller = new AbortController(); const signal = controller.signal; const url = "video.mp4"; const downloadBtn = document.querySelector(".download"); const abortBtn = document.querySelector(".abort"); downloadBtn.addEventListener("click", fetchVideo); abortBtn.addEventListener("click", () => { controller.abort(); console.log("Download aborted"); }); function fetchVideo() { fetch(url, { signal }) .then((response) => { console.log("Download complete", response); }) .catch((err) => { console.error(`Download error: ${err.message}`); }); } **Note:** When `abort()` is called, the `fetch()` promise rejects with an `AbortError`. You can find a full working example on GitHub; you can also see it running live. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `signal` | 66 | 16 | 57 | 53 | 12.111.1–12.1Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 66 | 57 | 47 | 12.211.3–12.2Even though `window.AbortController` is defined, it doesn't really abort `fetch` requests. See bug 174980. | 9.0 | 66 ## See also * Fetch API # AbortSignal Baseline Widely available * This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2018. * Some parts of this feature may have varying levels of support. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `AbortSignal` interface represents a signal object that allows you to communicate with an asynchronous operation (such as a fetch request) and abort it if required via an `AbortController` object. EventTarget AbortSignal ## Instance properties _Also inherits properties from its parent interface,`EventTarget`._ `AbortSignal.aborted` Read only A Boolean that indicates whether the request(s) the signal is communicating with is/are aborted (`true`) or not (`false`). `AbortSignal.reason` Read only A JavaScript value providing the abort reason, once the signal has aborted. ## Static methods _Also inherits methods from its parent interface,`EventTarget`._ `AbortSignal.abort()` Returns an `AbortSignal` instance that is already set as aborted. `AbortSignal.any()` Returns an `AbortSignal` that aborts when any of the given abort signals abort. `AbortSignal.timeout()` Returns an `AbortSignal` instance that will automatically abort after a specified time. ## Instance methods _Also inherits methods from its parent interface,`EventTarget`._ `AbortSignal.throwIfAborted()` Throws the signal's abort `reason` if the signal has been aborted; otherwise it does nothing. ## Events _Also inherits events from its parent interface,`EventTarget`._ Listen to this event using `addEventListener()` or by assigning an event listener to the `oneventname` property of this interface. `abort` Invoked when the asynchronous operations the signal is communicating with is/are aborted. Also available via the `onabort` property. ## Examples ### Aborting a fetch operation using an explicit signal The following snippet shows how we might use a signal to abort downloading a video using the Fetch API. We first create an abort controller using the `AbortController()` constructor, then grab a reference to its associated `AbortSignal` object using the `AbortController.signal` property. When the fetch request is initiated, we pass in the `AbortSignal` as an option inside the request's options object (the `{signal}` below). This associates the signal and controller with the fetch request, and allows us to abort it by calling `AbortController.abort()`. Below you can see that the fetch operation is aborted in the second event listener, which triggered when the abort button (`abortBtn`) is clicked. When `abort()` is called, the `fetch()` promise rejects with a `DOMException` named `AbortError`. let controller; const url = "video.mp4"; const downloadBtn = document.querySelector(".download"); const abortBtn = document.querySelector(".abort"); downloadBtn.addEventListener("click", fetchVideo); abortBtn.addEventListener("click", () => { if (controller) { controller.abort(); console.log("Download aborted"); } }); async function fetchVideo() { controller = new AbortController(); const signal = controller.signal; try { const response = await fetch(url, { signal }); console.log("Download complete", response); // process response further } catch (err) { console.error(`Download error: ${err.message}`); } } If the request is aborted after the `fetch()` call has been fulfilled but before the response body has been read, then attempting to read the response body will reject with an `AbortError` exception. async function get() { const controller = new AbortController(); const request = new Request("https://example.org/get", { signal: controller.signal, }); const response = await fetch(request); controller.abort(); // The next line will throw `AbortError` const text = await response.text(); console.log(text); } You can find a full working example on GitHub; you can also see it running live. ### Aborting a fetch operation with a timeout If you need to abort the operation on timeout then you can use the static `AbortSignal.timeout()` method. This returns an `AbortSignal` that will automatically timeout after a certain number of milliseconds. The code snippet below shows how you would either succeed in downloading a file, or handle a timeout error after 5 seconds. Note that when there is a timeout the `fetch()` promise rejects with a `TimeoutError` `DOMException`. This allows code to differentiate between timeouts (for which user notification is probably required), and user aborts. const url = "video.mp4"; try { const res = await fetch(url, { signal: AbortSignal.timeout(5000) }); const result = await res.blob(); // … } catch (err) { if (err.name === "TimeoutError") { console.error("Timeout: It took more than 5 seconds to get the result!"); } else if (err.name === "AbortError") { console.error( "Fetch aborted by user action (browser stop button, closing tab, etc.", ); } else { // A network error, or some other problem. console.error(`Error: type: ${err.name}, message: ${err.message}`); } } ### Aborting a fetch with timeout or explicit abort If you want to abort from multiple signals, you can use `AbortSignal.any()` to combine them into a single signal. The following example shows this using `fetch`: try { const controller = new AbortController(); const timeoutSignal = AbortSignal.timeout(5000); const res = await fetch(url, { // This will abort the fetch when either signal is aborted signal: AbortSignal.any([controller.signal, timeoutSignal]), }); const body = await res.json(); } catch (e) { if (e.name === "AbortError") { // Notify the user of abort. } else if (e.name === "TimeoutError") { // Notify the user of timeout } else { // A network error, or some other problem. console.log(`Type: ${e.name}, Message: ${e.message}`); } } **Note:** Unlike when using `AbortSignal.timeout()`, there is no way to tell whether the final abort was caused by a timeout. ### Implementing an abortable API An API that needs to support aborting can accept an `AbortSignal` object, and use its state to trigger abort signal handling when needed. A `Promise`-based API should respond to the abort signal by rejecting any unsettled promise with the `AbortSignal` abort `reason`. For example, consider the following `myCoolPromiseAPI`, which takes a signal and returns a promise. The promise is rejected immediately if the signal is already aborted, or if the abort event is detected. Otherwise it completes normally and then resolves the promise. function myCoolPromiseAPI(/* …, */ { signal }) { return new Promise((resolve, reject) => { // If the signal is already aborted, immediately throw in order to reject the promise. if (signal.aborted) { reject(signal.reason); return; } // Perform the main purpose of the API // Call resolve(result) when done. // Watch for 'abort' signals signal.addEventListener("abort", () => { // Stop the main operation // Reject the promise with the abort reason. reject(signal.reason); }); }); } The API might then be used as shown. Note that `AbortController.abort()` is called to abort the operation. const controller = new AbortController(); const signal = controller.signal; startSpinner(); myCoolPromiseAPI({ /* …, */ signal }) .then((result) => {}) .catch((err) => { if (err.name === "AbortError") return; showUserErrorMessage(); }) .then(() => stopSpinner()); controller.abort(); APIs that do not return promises might react in a similar manner. In some cases it may make sense to absorb the signal. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `AbortSignal` | 66 | 16 | 57 | 53 | 11.1 | 66 | 57 | 47 | 11.3 | 9.0 | 66 `abort_event` | 66 | 16 | 57 | 53 | 11.1 | 66 | 57 | 47 | 11.3 | 9.0 | 66 `abort_static` | 93 | 93 | 88 | 79 | 15 | 93 | 88 | 66 | 15 | 17.0 | 93 `aborted` | 66 | 16 | 57 | 53 | 11.1 | 66 | 57 | 47 | 11.3 | 9.0 | 66 `any_static` | 116 | 116 | 124 | 102 | 17.4 | 116 | 124 | 78 | 17.4 | 24.0 | 116 `reason` | 98 | 98 | 97 | 84 | 15.4 | 98 | 97 | 68 | 15.4 | 18.0 | 98 `throwIfAborted` | 100 | 100 | 97 | 86 | 15.4 | 100 | 97 | 69 | 15.4 | 19.0 | 100 `timeout_static` | 124103–124Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 124103–124Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 100 | 11089–110Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 16 | 124103–124Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 100 | 8271–82Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 16 | 27.020.0–27.0Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 124103–124Always aborts with an `AbortError` on timeout, not a `TimeoutError`. ## See also * Fetch API * Abortable Fetch by Jake Archibald # AbortSignal: abort event Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2018. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `abort` event of the `AbortSignal` is fired when the associated request is aborted, i.e., using `AbortController.abort()`. ## Syntax Use the event name in methods like `addEventListener()`, or set an event handler property. addEventListener("abort", (event) => { }) onabort = (event) => { } ## Event type A generic `Event` with no added properties. ## Examples In the following snippets, we create a new `AbortController` object, and get its `AbortSignal` (available using the `signal` property). Later on we check whether or not the signal has been aborted using an event handler property, You can detect the `abort` event using an `addEventListener` method: const controller = new AbortController(); const signal = controller.signal; signal.addEventListener("abort", () => { console.log("Request aborted"); }); Or use the `onabort` event handler property: const controller = new AbortController(); const signal = controller.signal; signal.onabort = () => { console.log("Request aborted"); }; ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `abort_event` | 66 | 16 | 57 | 53 | 11.1 | 66 | 57 | 47 | 11.3 | 9.0 | 66 # AbortSignal: abort() static method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2021. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `AbortSignal.abort()` static method returns an `AbortSignal` that is already set as aborted (and which does not trigger an `abort` event). This is shorthand for the following code: const controller = new AbortController(); controller.abort(); return controller.signal; This could, for example, be passed to a fetch method in order to run its abort logic (i.e., it may be that code is organized such that the abort logic should be run even if the intended fetch operation has not been started). **Note:** The method is similar in purpose to `Promise.reject`. ## Syntax AbortSignal.abort() AbortSignal.abort(reason) ### Parameters `reason` The reason why the operation was aborted, which can be any JavaScript value. If not specified, the reason is set to "AbortError" `DOMException`. ### Return value An `AbortSignal` instance with the `AbortSignal.aborted` property set to `true`, and `AbortSignal.reason` set to the specified or default reason value. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `abort_static` | 93 | 93 | 88 | 79 | 15 | 93 | 88 | 66 | 15 | 17.0 | 93 `reason_parameter` | 98 | 98 | 97 | 84 | 15.4 | 98 | 97 | 68 | 15.4 | 18.0 | 98 # AbortSignal: aborted property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2018. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `aborted` read-only property returns a value that indicates whether the asynchronous operations the signal is communicating with are aborted (`true`) or not (`false`). ## Value `true` (aborted) or `false` ## Examples In the following snippet, we create a new `AbortController` object, and get its `AbortSignal` (available using the `signal` property). Later on, using the `aborted` property, we check whether or not the signal has been aborted, and send an appropriate log to the console. const controller = new AbortController(); const signal = controller.signal; // … if (signal.aborted) { console.log("Request has been aborted"); } else { console.log("Request not aborted"); } ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `aborted` | 66 | 16 | 57 | 53 | 11.1 | 66 | 57 | 47 | 11.3 | 9.0 | 66 ## See also * Fetch API # AbortSignal: any() static method Baseline 2024 Newly available Since March 2024, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `AbortSignal.any()` static method takes an iterable of abort signals and returns an `AbortSignal`. The returned abort signal is aborted when any of the input iterable abort signals are aborted. The abort reason will be set to the reason of the first signal that is aborted. If any of the given abort signals are already aborted then so will be the returned `AbortSignal`. ## Syntax AbortSignal.any(iterable) ### Parameters `iterable` An iterable (such as an `Array`) of abort signals. ### Return value A `AbortSignal` that is: * **Already aborted** , if any of the abort signals given is already aborted. The returned `AbortSignal`'s reason will be already set to the `reason` of the first abort signal that was already aborted. * **Asynchronously aborted** , when any abort signal in `iterable` aborts. The `reason` will be set to the reason of the first abort signal that is aborted. ## Examples ### Using `AbortSignal.any()` This example demonstrates combining both a signal from an `AbortController`, and a timeout signal from `AbortSignal.timeout`. const cancelDownloadButton = document.getElementById("cancelDownloadButton"); const userCancelController = new AbortController(); cancelDownloadButton.addEventListener("click", () => { userCancelController.abort(); }); // Timeout after 5 minutes const timeoutSignal = AbortSignal.timeout(1_000 * 60 * 5); // This signal will abort when either the user clicks the cancel button or 5 minutes is up // whichever is sooner const combinedSignal = AbortSignal.any([ userCancelController.signal, timeoutSignal, ]); try { const res = await fetch(someUrlToDownload, { // Stop the fetch when any of the signals aborts signal: combinedSignal, }); const body = await res.blob(); // Do something with downloaded content: // … } catch (e) { if (e.name === "AbortError") { // Cancelled by the user } else if (e.name === "TimeoutError") { // Show user that download timed out } else { // Other error, e.g. network error } } ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `any_static` | 116 | 116 | 124 | 102 | 17.4 | 116 | 124 | 78 | 17.4 | 24.0 | 116 # AbortSignal: reason property Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2022. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `reason` read-only property returns a JavaScript value that indicates the abort reason. The property is `undefined` when the signal has not been aborted. It can be set to a specific value when the signal is aborted, using `AbortController.abort()` or `AbortSignal.abort()`. If not explicitly set in those methods, it defaults to "AbortError" `DOMException`. ## Value A JavaScript value that indicates the abort reason, or `undefined`, if not aborted. ## Examples In the following snippet, we create a new `AbortController` object, and get its `AbortSignal` (available using the `signal` property). Later on, using the `aborted` property, we check whether or not the signal has been aborted, and log the abort status and reason to the console. const controller = new AbortController(); const signal = controller.signal; // … if (signal.aborted) { if (signal.reason) { console.log(`Request aborted with reason: ${signal.reason}`); } else { console.log("Request aborted but no reason was given."); } } else { console.log("Request not aborted"); } ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `reason` | 98 | 98 | 97 | 84 | 15.4 | 98 | 97 | 68 | 15.4 | 18.0 | 98 ## See also * Fetch API # AbortSignal: throwIfAborted() method Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2022. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `throwIfAborted()` method throws the signal's abort `reason` if the signal has been aborted; otherwise it does nothing. An API that needs to support aborting can accept an `AbortSignal` object and use `throwIfAborted()` to test and throw when the `abort` event is signalled. This method can also be used to abort operations at particular points in code, rather than passing to functions that take a signal. ## Syntax throwIfAborted() ### Parameters None. ### Return value None (`undefined`). ## Examples The examples below come from the specification. ### Aborting a polling operation This example demonstrates how you can use `throwIfAborted()` to abort a polling operation. Consider an asynchronous `waitForCondition()` function that is called with another asynchronous function `func`, a target value `targetValue`, and an `AbortSignal`. The method compares the result of `func` with `targetValue` in a loop, returning when they match. async function waitForCondition(func, targetValue, { signal } = {}) { while (true) { signal?.throwIfAborted(); const result = await func(); if (result === targetValue) { return; } } } On each iteration of the loop, we use `throwIfAborted()` to throw the signal's `reason` if the operation has been aborted (and otherwise do nothing). If the signal is aborted, this will cause the `waitForCondition()` promise to be rejected. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `throwIfAborted` | 100 | 100 | 97 | 86 | 15.4 | 100 | 97 | 69 | 15.4 | 19.0 | 100 ## See also * Fetch API # AbortSignal: timeout() static method Baseline 2024 Newly available Since April 2024, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers. * Learn more * See full compatibility * Report feedback **Note:** This feature is available in Web Workers. The `AbortSignal.timeout()` static method returns an `AbortSignal` that will automatically abort after a specified time. The signal aborts with a `TimeoutError` `DOMException` on timeout. The timeout is based on active rather than elapsed time, and will effectively be paused if the code is running in a suspended worker, or while the document is in a back-forward cache ("bfcache"). To combine multiple signals, you can use `AbortSignal.any()`, for example, to directly abort a download using either a timeout signal or by calling `AbortController.abort()`. ## Syntax AbortSignal.timeout(time) ### Parameters `time` The "active" time in milliseconds before the returned `AbortSignal` will abort. The value must be within range of 0 and `Number.MAX_SAFE_INTEGER`. ### Return value An `AbortSignal`. The signal will abort with its `AbortSignal.reason` property set to a `TimeoutError` `DOMException` on timeout, or an `AbortError` `DOMException` if the operation was user-triggered. ## Examples Below is an example showing a fetch operation that will timeout if unsuccessful after 5 seconds. Note that this may also fail if the method is not supported, if a browser "stop" button is pressed, or for another reason. const url = "https://path_to_large_file.mp4"; try { const res = await fetch(url, { signal: AbortSignal.timeout(5000) }); const result = await res.blob(); // … } catch (err) { if (err.name === "TimeoutError") { // This exception is from the abort signal console.error("Timeout: It took more than 5 seconds to get the result!"); } else if (err.name === "AbortError") { // This exception is from the fetch itself console.error( "Fetch aborted by user action (browser stop button, closing tab, etc.", ); } else if (err.name === "TypeError") { console.error("AbortSignal.timeout() method is not supported"); } else { // A network error, or some other problem. console.error(`Error: type: ${err.name}, message: ${err.message}`); } } ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `timeout_static` | 124103–124Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 124103–124Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 100 | 11089–110Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 16 | 124103–124Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 100 | 8271–82Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 16 | 27.020.0–27.0Always aborts with an `AbortError` on timeout, not a `TimeoutError`. | 124103–124Always aborts with an `AbortError` on timeout, not a `TimeoutError`. # AbsoluteOrientationSensor Limited availability This feature is not Baseline because it does not work in some of the most widely-used browsers. * Learn more * See full compatibility * Report feedback **Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers. The `AbsoluteOrientationSensor` interface of the Sensor APIs describes the device's physical orientation in relation to the Earth's reference coordinate system. To use this sensor, the user must grant permission to the `'accelerometer'`, `'gyroscope'`, and `'magnetometer'` device sensors through the Permissions API. This feature may be blocked by a Permissions Policy set on your server. EventTarget Sensor OrientationSensor AbsoluteOrientationSensor ## Constructor `AbsoluteOrientationSensor()` Creates a new `AbsoluteOrientationSensor` object. ## Instance properties _No specific properties; inherits properties from its ancestors`OrientationSensor` and `Sensor`._ ## Instance methods _No specific methods; inherits methods from its ancestors`OrientationSensor` and `Sensor`._ ## Events _No specific events; inherits methods from its ancestor,`Sensor`._ ## Examples ### Basic Example The following example, which is loosely based on Intel's Orientation Phone demo, instantiates an `AbsoluteOrientationSensor` with a frequency of 60 times a second. On each reading it uses `OrientationSensor.quaternion` to rotate a visual model of a phone. const options = { frequency: 60, referenceFrame: "device" }; const sensor = new AbsoluteOrientationSensor(options); sensor.addEventListener("reading", () => { // model is a Three.js object instantiated elsewhere. model.quaternion.fromArray(sensor.quaternion).inverse(); }); sensor.addEventListener("error", (event) => { if (event.error.name === "NotReadableError") { console.log("Sensor is not available."); } }); sensor.start(); ### Permissions Example Using orientation sensors requires requesting permissions for multiple device sensors. Because the `Permissions` interface uses promises, a good way to request permissions is to use `Promise.all`. const sensor = new AbsoluteOrientationSensor(); Promise.all([ navigator.permissions.query({ name: "accelerometer" }), navigator.permissions.query({ name: "magnetometer" }), navigator.permissions.query({ name: "gyroscope" }), ]).then((results) => { if (results.every((result) => result.state === "granted")) { sensor.start(); // … } else { console.log("No permissions to use AbsoluteOrientationSensor."); } }); ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `AbsoluteOrientationSensor` | 67 | 79 | No | 54 | No | 67 | No | 48 | No | 9.0 | 67 `AbsoluteOrientationSensor` | 67 | 79 | No | 54 | No | 67 | No | 48 | No | 9.0 | 67 # AbsoluteOrientationSensor: AbsoluteOrientationSensor() constructor Limited availability This feature is not Baseline because it does not work in some of the most widely-used browsers. * Learn more * See full compatibility * Report feedback **Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers. The `AbsoluteOrientationSensor()` constructor creates a new `AbsoluteOrientationSensor` object which describes the device's physical orientation in relation to the Earth's reference coordinate system. ## Syntax new AbsoluteOrientationSensor() new AbsoluteOrientationSensor(options) ### Parameters `options` Optional Options are as follows: `frequency` Optional The desired number of times per second a sample should be taken, meaning the number of times per second that the `reading` event will be called. A whole number or decimal may be used, the latter for frequencies less than a second. The actual reading frequency depends on the device hardware and consequently may be less than requested. `referenceFrame` Optional Either `'device'` or `'screen'`. The default is `'device'`. ## Specifications ## Browser compatibility | Desktop | Mobile ---|---|--- | Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android `AbsoluteOrientationSensor` | 67 | 79 | No | 54 | No | 67 | No | 48 | No | 9.0 | 67 ## See also * `reading` event # AbstractRange Baseline Widely available This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2021. * Learn more * See full compatibility * Report feedback The `AbstractRange` abstract interface is the base class upon which all DOM range types are defined. A **range** is an object that indicates the start and end points of a section of content within the document. **Note:** As an abstract interface, you will not directly instantiate an object of type `AbstractRange`. Instead, you will use the `Range` or `StaticRange` interfaces. To understand the difference between those two interfaces, and how to choose which is appropriate for your needs, consult each interface's documentation. ## Instance properties `collapsed` Read only A Boolean value which is `true` if the range is _collapsed_. A collapsed range is a range whose start position and end position are the same, resulting in a zero-character-long range. `endContainer` Read only The `Node` object in which the end of the range, as specified by the `endOffset` property, is located. `endOffset` Read only An integer value indicating the offset, in characters, from the beginning of the node's contents to the last character of the range represented by the range object. This value must be less than the length of the `endContainer` node. `startContainer` Read only The DOM `Node` in which the beginning of the range, as specified by the `startOffset` property, is located. `startOffset` Read only An integer value indicating the offset, in characters, from the beginning of the node's contents to the first character of the contents referred to by the range object. This value must be less than the length of the node indicated in `startContainer`. ## Instance methods _The`AbstractRange` interface doesn't provide any methods._ ## Usage notes ### Range types All ranges of content within a `document` are described using instances of interfaces based on `AbstractRange`. There are two such interfaces: `Range` The `Range` interface has been around for a long time and has only recently been redefined to be based upon `AbstractRange` as the need arose to define other forms of range data. `Range` provides methods that allow you to alter the range's endpoints, as well as methods to compare ranges, detect intersections between ranges, and so forth. `StaticRange` A `StaticRange` is a basic range which cannot be changed once it's been created. Specifically, as the node tree mutates and changes, the range does not. This is useful when you need to specify a range that will only be used once, since it avoids the performance and resource impact of the more complex `Range` interface. ### Contents of elements When trying to access the contents of an element, keep in mind that the element itself is a node, but so is any text inside it. In order to set a range endpoint within the text of an element, be sure to find the text node inside the element: const startElem = document.querySelector("p"); const endElem = startElem.querySelector("span"); const range = document.createRange(); range.setStart(startElem, 0); range.setEnd(endElem, endElem.childNodes[0].length / 2); const contents = range.cloneContents(); document.body.appendChild(contents); This example creates a new range, `range`, and sets its starting point to the third child node of the first element. The end point is set to be the middle of the first child of the span, and then the range is used to copy the contents of the range. ### Ranges and the hierarchy of the DOM In order to define a range of characters within a document in a way that is able to span across zero or more node boundaries, and which is as resilient as possible to changes to the DOM, you can't specify the offset to the first and last characters in the HTML. There are a few good reasons for that. First, after your page is loaded, the browser isn't thinking in terms of HTML. Once it's been loaded, the page is a tree of DOM `Node` objects, so you need to specify the beginning and ending locations of a range in terms of nodes and positions within nodes. Second, in order to support the mutability of the DOM tree as much as possible, you need a way to represent positions relative to nodes in the tree, rather than global positions within the entire document. By defining points within the document as offsets within a given node, those positions remain consistent with the content even as nodes are added to, removed from, or moved around within the DOM tree—within reason. There are fairly obvious limitations (such as if a node is moved to be after the endpoint of a range, or if the content of a node is heavily altered), but it's far better than nothing. Third, using node-relative positions to define the start and end positions will generally be easier to make perform well. Rather than having to negotiate the DOM figuring out what your global offset refers to, the user agent (browser) can instead go directly to the node indicated by the starting position and start from there, working its way forward until it reaches the given offset into the ending node. To illustrate this, consider the HTML below:
A very interesting thing happened on the way to the forum…
` element whose contents are `"A very interesting thing happened on the way to the forum…"`, you can do so like this: const pRange = document.createRange(); pRange.selectNodeContents(document.querySelector("#entry1 p")); Since we wish to select the entire contents of the `
` element, including
its descendants, this works perfectly.
If we wish to instead copy the text "An interesting thing…" from the
` ` element, so that will be needed
within the new fragment. So will the text node containing the word "A", since
that's included in the range. Finally, an `` and a text node below it will
be added below the ` ` as well.
The contents of the text nodes are then determined by the offsets into those
text nodes given when calling `setStart()` and `setEnd()`. Given the offset of
11 into the heading's text, that node will contain "An interesting thing…".
Similarly, the last text node will contain "ve", given the request for the
first two characters of the ending node.
The resulting document fragment looks like this:
Notice especially that the contents of this fragment are all _below_ the
shared common parent of the topmost nodes within it. The parent ` This is a paragraph.