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.

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 define a variable for our AbortController.

Before each fetch request we create a new controller using the AbortController() constructor, then grab a reference to its associated AbortSignal object using the AbortController.signal property.

Note: An AbortSignal can only be used once. After it is aborted, any fetch call using the same signal will be immediately rejected.

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.

js
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.

js
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.

js
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:

js
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.

js
function myCoolPromiseAPI(/* …, */ { signal }) {
  return new Promise((resolve, reject) => {
    // If the signal is already aborted, immediately throw in order to reject the promise.
    signal.throwIfAborted();

    // Perform the main purpose of the API
    // Call resolve(result) when done.

    // Watch for 'abort' signals
    // Passing `once: true` ensures the Promise can be garbage collected after abort is called
    signal.addEventListener(
      "abort",
      () => {
        // Stop the main operation
        // Reject the promise with the abort reason.
        reject(signal.reason);
      },
      { once: true },
    );
  });
}

The API might then be used as shown. Note that AbortController.abort() is called to abort the operation.

js
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

Specification
DOM
# interface-AbortSignal

Browser compatibility

desktop mobile server
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
Bun
Deno
Node.js
AbortSignal
Chrome – Full support
Chrome 66 (Release date: 2018-04-17)
footnote Full support
Edge – Full support
Edge 16 (Release date: 2017-10-17)
footnote Full support
Firefox – Full support
Firefox 57 (Release date: 2017-11-14)
footnote Full support
Opera – Full support
Opera 53 (Release date: 2018-05-10)
footnote Full support
Safari – Full support
Safari 11.1 (Release date: 2018-04-12)
footnote Full support
Chrome Android – Full support
Chrome Android 66 (Release date: 2018-04-17)
footnote Full support
Firefox for Android – Full support
Firefox for Android 57 (Release date: 2017-11-28)
footnote Full support
Opera Android – Full support
Opera Android 47 (Release date: 2018-07-23)
footnote Full support
Safari on iOS – Full support
Safari on iOS 11.3 (Release date: 2018-03-29)
footnote Full support
Samsung Internet – Full support
Samsung Internet 9 (Release date: 2018-09-15)
footnote Full support
WebView Android – Full support
WebView Android 66 (Release date: 2018-04-17)
footnote Full support
WebView on iOS – Full support
WebView on iOS 11.3 (Release date: 2018-03-29)
footnote Full support
Bun – Full support
Bun 1 (Release date: 2023-09-08)
footnote Full support
Deno – Full support
Deno 1 (Release date: 2020-05-13)
footnote Full support
Node.js – Full support
Node.js 14.17 (Release date: 2021-05-11)
footnote Full support
abort event
Chrome – Full support
Chrome 66 (Release date: 2018-04-17)
footnote Full support
Edge – Full support
Edge 16 (Release date: 2017-10-17)
footnote Full support
Firefox – Full support
Firefox 57 (Release date: 2017-11-14)
footnote Full support
Opera – Full support
Opera 53 (Release date: 2018-05-10)
footnote Full support
Safari – Full support
Safari 11.1 (Release date: 2018-04-12)
footnote Full support
Chrome Android – Full support
Chrome Android 66 (Release date: 2018-04-17)
footnote Full support
Firefox for Android – Full support
Firefox for Android 57 (Release date: 2017-11-28)
footnote Full support
Opera Android – Full support
Opera Android 47 (Release date: 2018-07-23)
footnote Full support
Safari on iOS – Full support
Safari on iOS 11.3 (Release date: 2018-03-29)
footnote Full support
Samsung Internet – Full support
Samsung Internet 9 (Release date: 2018-09-15)
footnote Full support
WebView Android – Full support
WebView Android 66 (Release date: 2018-04-17)
footnote Full support
WebView on iOS – Full support
WebView on iOS 11.3 (Release date: 2018-03-29)
footnote Full support
Bun – Full support
Bun 1 (Release date: 2023-09-08)
footnote Full support
Deno – Full support
Deno 1 (Release date: 2020-05-13)
footnote Full support
Node.js – Full support
Node.js 14.17 (Release date: 2021-05-11)
footnote Full support
abort() static method
Chrome – Full support
Chrome 93 (Release date: 2021-08-31)
footnote Full support
Edge – Full support
Edge 93 (Release date: 2021-09-02)
footnote Full support
Firefox – Full support
Firefox 88 (Release date: 2021-04-19)
footnote Full support
Opera – Full support
Opera 79 (Release date: 2021-09-14)
footnote Full support
Safari – Full support
Safari 15 (Release date: 2021-09-20)
footnote Full support
Chrome Android – Full support
Chrome Android 93 (Release date: 2021-08-31)
footnote Full support
Firefox for Android – Full support
Firefox for Android 88 (Release date: 2021-04-19)
footnote Full support
Opera Android – Full support
Opera Android 66 (Release date: 2021-12-15)
footnote Full support
Safari on iOS – Full support
Safari on iOS 15 (Release date: 2021-09-20)
footnote Full support
Samsung Internet – Full support
Samsung Internet 17 (Release date: 2022-05-04)
footnote Full support
WebView Android – Full support
WebView Android 93 (Release date: 2021-08-31)
footnote Full support
WebView on iOS – Full support
WebView on iOS 15 (Release date: 2021-09-20)
footnote Full support
Bun – Full support
Bun 1 (Release date: 2023-09-08)
footnote Full support
Deno – Full support
Deno 1.9 (Release date: 2021-04-13)
footnote Full support
Node.js – No support
Node.js 14.17 – 14.18 (Release date: 2021-05-11)
footnote Removed in 15 and later
Node.js – Full support
Node.js 15.12 (Release date: 2021-03-17)
footnote Full support
reason parameter
Chrome – Full support
Chrome 98 (Release date: 2022-02-01)
footnote Full support
Edge – Full support
Edge 98 (Release date: 2022-02-03)
footnote Full support
Firefox – Full support
Firefox 97 (Release date: 2022-02-08)
footnote Full support
Opera – Full support
Opera 84 (Release date: 2022-02-16)
footnote Full support
Safari – Full support
Safari 15.4 (Release date: 2022-03-14)
footnote Full support
Chrome Android – Full support
Chrome Android 98 (Release date: 2022-02-01)
footnote Full support
Firefox for Android – Full support
Firefox for Android 97 (Release date: 2022-02-08)
footnote Full support
Opera Android – Full support
Opera Android 68 (Release date: 2022-03-30)
footnote Full support
Safari on iOS – Full support
Safari on iOS 15.4 (Release date: 2022-03-14)
footnote Full support
Samsung Internet – Full support
Samsung Internet 18 (Release date: 2022-08-08)
footnote Full support
WebView Android – Full support
WebView Android 98 (Release date: 2022-02-01)
footnote Full support
WebView on iOS – Full support
WebView on iOS 15.4 (Release date: 2022-03-14)
footnote Full support
Bun – Full support
Bun 1 (Release date: 2023-09-08)
footnote Full support
Deno – Full support
Deno 1.16 (Release date: 2021-11-08)
footnote Full support
Node.js – No support
Node.js 16.14 – 16.17 (Release date: 2022-02-08)
footnote Removed in 17 and later
Node.js – Full support
Node.js 17.2 (Release date: 2021-11-30)
footnote Full support
aborted
Chrome – Full support
Chrome 66 (Release date: 2018-04-17)
footnote Full support
Edge – Full support
Edge 16 (Release date: 2017-10-17)
footnote Full support
Firefox – Full support
Firefox 57 (Release date: 2017-11-14)
footnote Full support
Opera – Full support
Opera 53 (Release date: 2018-05-10)
footnote Full support
Safari – Full support
Safari 11.1 (Release date: 2018-04-12)
footnote Full support
Chrome Android – Full support
Chrome Android 66 (Release date: 2018-04-17)
footnote Full support
Firefox for Android – Full support
Firefox for Android 57 (Release date: 2017-11-28)
footnote Full support
Opera Android – Full support
Opera Android 47 (Release date: 2018-07-23)
footnote Full support
Safari on iOS – Full support
Safari on iOS 11.3 (Release date: 2018-03-29)
footnote Full support
Samsung Internet – Full support
Samsung Internet 9 (Release date: 2018-09-15)
footnote Full support
WebView Android – Full support
WebView Android 66 (Release date: 2018-04-17)
footnote Full support
WebView on iOS – Full support
WebView on iOS 11.3 (Release date: 2018-03-29)
footnote Full support
Bun – Full support
Bun 1 (Release date: 2023-09-08)
footnote Full support
Deno – Full support
Deno 1 (Release date: 2020-05-13)
footnote Full support
Node.js – Full support
Node.js 14.17 (Release date: 2021-05-11)
footnote Full support
any() static method
Chrome – Full support
Chrome 116 (Release date: 2023-08-15)
footnote Full support
Edge – Full support
Edge 116 (Release date: 2023-08-21)
footnote Full support
Firefox – Full support
Firefox 124 (Release date: 2024-03-19)
footnote Full support
Opera – Full support
Opera 102 (Release date: 2023-08-23)
footnote Full support
Safari – Full support
Safari 17.4 (Release date: 2024-03-05)
footnote Full support
Chrome Android – Full support
Chrome Android 116 (Release date: 2023-08-15)
footnote Full support
Firefox for Android – Full support
Firefox for Android 124 (Release date: 2024-03-19)
footnote Full support
Opera Android – Full support
Opera Android 78 (Release date: 2023-10-23)
footnote Full support
Safari on iOS – Full support
Safari on iOS 17.4 (Release date: 2024-03-05)
footnote Full support
Samsung Internet – Full support
Samsung Internet 24 (Release date: 2024-01-25)
footnote Full support
WebView Android – Full support
WebView Android 116 (Release date: 2023-08-15)
footnote Full support
WebView on iOS – Full support
WebView on iOS 17.4 (Release date: 2024-03-05)
footnote Full support
Bun – Full support
Bun 1.1.4 (Release date: 2024-04-16)
footnote Full support
Deno – Full support
Deno 1.39 (Release date: 2023-12-14)
footnote Full support
Node.js – No support
Node.js 18.17 – 18.20 (Release date: 2023-07-18)
footnote Removed in 19 and later
Node.js – Full support
Node.js 20.3 (Release date: 2023-06-08)
footnote Full support
reason
Chrome – Full support
Chrome 98 (Release date: 2022-02-01)
footnote Full support
Edge – Full support
Edge 98 (Release date: 2022-02-03)
footnote Full support
Firefox – Full support
Firefox 97 (Release date: 2022-02-08)
footnote Full support
Opera – Full support
Opera 84 (Release date: 2022-02-16)
footnote Full support
Safari – Full support
Safari 15.4 (Release date: 2022-03-14)
footnote Full support
Chrome Android – Full support
Chrome Android 98 (Release date: 2022-02-01)
footnote Full support
Firefox for Android – Full support
Firefox for Android 97 (Release date: 2022-02-08)
footnote Full support
Opera Android – Full support
Opera Android 68 (Release date: 2022-03-30)
footnote Full support
Safari on iOS – Full support
Safari on iOS 15.4 (Release date: 2022-03-14)
footnote Full support
Samsung Internet – Full support
Samsung Internet 18 (Release date: 2022-08-08)
footnote Full support
WebView Android – Full support
WebView Android 98 (Release date: 2022-02-01)
footnote Full support
WebView on iOS – Full support
WebView on iOS 15.4 (Release date: 2022-03-14)
footnote Full support
Bun – Full support
Bun 1 (Release date: 2023-09-08)
footnote Full support
Deno – Full support
Deno 1.16 (Release date: 2021-11-08)
footnote Full support
Node.js – No support
Node.js 16.14 – 16.17 (Release date: 2022-02-08)
footnote Removed in 17 and later
Node.js – Full support
Node.js 17.2 (Release date: 2021-11-30)
footnote Full support
throwIfAborted
Chrome – Full support
Chrome 100 (Release date: 2022-03-29)
footnote Full support
Edge – Full support
Edge 100 (Release date: 2022-04-01)
footnote Full support
Firefox – Full support
Firefox 97 (Release date: 2022-02-08)
footnote Full support
Opera – Full support
Opera 86 (Release date: 2022-04-20)
footnote Full support
Safari – Full support
Safari 15.4 (Release date: 2022-03-14)
footnote Full support
Chrome Android – Full support
Chrome Android 100 (Release date: 2022-03-29)
footnote Full support
Firefox for Android – Full support
Firefox for Android 97 (Release date: 2022-02-08)
footnote Full support
Opera Android – Full support
Opera Android 69 (Release date: 2022-05-09)
footnote Full support
Safari on iOS – Full support
Safari on iOS 15.4 (Release date: 2022-03-14)
footnote Full support
Samsung Internet – Full support
Samsung Internet 19 (Release date: 2022-11-01)
footnote Full support
WebView Android – Full support
WebView Android 100 (Release date: 2022-03-29)
footnote Full support
WebView on iOS – Full support
WebView on iOS 15.4 (Release date: 2022-03-14)
footnote Full support
Bun – Full support
Bun 1 (Release date: 2023-09-08)
footnote Full support
Deno – Full support
Deno 1.17 (Release date: 2021-12-16)
footnote Full support
Node.js – No support
Node.js 16.17 – 16.17 (Release date: 2022-08-16)
footnote Removed in 17 and later
Node.js – Full support
Node.js 17.3 (Release date: 2021-12-17)
footnote Full support
timeout() static method
Chrome – Partial support
Chrome 103 – 123 (Release date: 2022-06-21)
footnote Partial support
footnote Always aborts with an AbortError on timeout, not a TimeoutError.
Chrome – Full support
Chrome 124 (Release date: 2024-04-16)
footnote Full support
Edge – Partial support
Edge 103 – 123 (Release date: 2022-06-23)
footnote Partial support
footnote Always aborts with an AbortError on timeout, not a TimeoutError.
Edge – Full support
Edge 124 (Release date: 2024-04-18)
footnote Full support
Firefox – Full support
Firefox 100 (Release date: 2022-05-03)
footnote Full support
Opera – Partial support
Opera 89 – 109 (Release date: 2022-07-07)
footnote Partial support
footnote Always aborts with an AbortError on timeout, not a TimeoutError.
Opera – Full support
Opera 110 (Release date: 2024-05-14)
footnote Full support
Safari – Full support
Safari 16 (Release date: 2022-09-12)
footnote Full support
Chrome Android – Partial support
Chrome Android 103 – 123 (Release date: 2022-06-21)
footnote Partial support
footnote Always aborts with an AbortError on timeout, not a TimeoutError.
Chrome Android – Full support
Chrome Android 124 (Release date: 2024-04-16)
footnote Full support
Firefox for Android – Full support
Firefox for Android 100 (Release date: 2022-05-03)
footnote Full support
Opera Android – Partial support
Opera Android 71 – 81 (Release date: 2022-09-16)
footnote Partial support
footnote Always aborts with an AbortError on timeout, not a TimeoutError.
Opera Android – Full support
Opera Android 82 (Release date: 2024-05-02)
footnote Full support
Safari on iOS – Full support
Safari on iOS 16 (Release date: 2022-09-12)
footnote Full support
Samsung Internet – Partial support
Samsung Internet 20 – 26 (Release date: 2023-02-10)
footnote Partial support
footnote Always aborts with an AbortError on timeout, not a TimeoutError.
Samsung Internet – Full support
Samsung Internet 27 (Release date: 2024-11-06)
footnote Full support
WebView Android – Partial support
WebView Android 103 – 123 (Release date: 2022-06-21)
footnote Partial support
footnote Always aborts with an AbortError on timeout, not a TimeoutError.
WebView Android – Full support
WebView Android 124 (Release date: 2024-04-16)
footnote Full support
WebView on iOS – Full support
WebView on iOS 16 (Release date: 2022-09-12)
footnote Full support
Bun – Full support
Bun 1 (Release date: 2023-09-08)
footnote Full support
Deno – Full support
Deno 1.20 (Release date: 2022-03-17)
footnote Full support
Node.js – No support
Node.js 16.14 – 16.17 (Release date: 2022-02-08)
footnote Removed in 17 and later
Node.js – Full support
Node.js 17.3 (Release date: 2021-12-17)
footnote Full support

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support
Partial support
Partial support
Has more compatibility info.

See also