Skip to main content

What do AbortController and AbortSignal do?

What AbortController is

AbortController is a controller that creates a signal (AbortSignal) and can "pull" it (cancel it).

In simpler terms: AbortController is the "remote", AbortSignal is the "wire" plugged into the operation.


Example

javascript
const controller = new AbortController(); const { signal } = controller; fetch('https://example.com/data', { signal }) .then(res => res.json()) .then(data => console.log('Success:', data)) .catch(err => { if (err.name === 'AbortError') { console.log('Request canceled!'); } else { console.error('Error:', err); } }); // Cancel the request after 2 seconds setTimeout(() => controller.abort(), 2000);

What happens:

  1. A controller is created.
  2. signal is pulled out of it.
  3. signal is passed into fetch.
  4. After 2 seconds, controller.abort() is called.
  5. fetch is interrupted and returns an AbortError.

How it works internally

AbortController

  • Has the methods:

    javascript
    controller.abort(reason?) // cancel the operation controller.signal // reference to the signal

AbortSignal

  • Holds the state:

    javascript
    signal.aborted // true, if already canceled
  • Can listen for an event:

    javascript
    signal.addEventListener('abort', () => console.log('Canceled!'));

Example of working with several tasks

You can use a single controller for several operations at once:

javascript
const controller = new AbortController(); fetch('/users', { signal: controller.signal }); fetch('/posts', { signal: controller.signal }); // cancel both operations at once controller.abort();

Both requests will be interrupted.


You can specify a cancellation reason

javascript
controller.abort('Manual cancellation'); signal.addEventListener('abort', e => { console.log(e.target.reason); // "Manual cancellation" });

(Supported in modern browsers and Node 18+)


Using it with Promise.race for a timeout

javascript
function fetchWithTimeout(url, ms) { const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), ms); return fetch(url, { signal: controller.signal }) .finally(() => clearTimeout(timeout)); } fetchWithTimeout('/api/data', 2000) .then(r => r.json()) .then(console.log) .catch(err => { if (err.name === 'AbortError') console.log('Timeout!'); });

A handy pattern: cancellation once the time runs out.


You can listen for cancellation manually (not only in fetch)

javascript
function wait(ms, signal) { return new Promise((resolve, reject) => { const timeout = setTimeout(resolve, ms); signal.addEventListener('abort', () => { clearTimeout(timeout); reject(new Error('Canceled')); }); }); } const controller = new AbortController(); wait(5000, controller.signal).catch(console.error); setTimeout(() => controller.abort(), 2000);

Here wait() is a custom function, but it can react to AbortSignal, just like fetch.


Support

Works in:

  • all modern browsers (Chrome, Firefox, Safari, Edge)
  • Node.js 16.5+ (in fetch, stream, setTimeout)

A simple analogy

AbortController is the remote control.

AbortSignal is the wire connected to the task.

When you press abort(), the signal travels down the wire and tells the task: "Stop!"


SUMMARY

ObjectWhat it doesMain properties/methods
AbortControllerManages cancellation.abort(), .signal
AbortSignalPassed into an operation to listen for cancellation.aborted, .addEventListener('abort')
Typical errorAbortError - thrown on cancellation
Typical scenariosCanceling fetch, timeouts, interrupting several tasks

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.