AbortController

Cancel In-Flight Async Operations

AbortController

AbortController is the standard cancellation primitive. Pass its signal to fetch, fs, timers, your own functions.

3 min read Level 2/5 #nodejs#abort#cancellation
What you'll learn
  • Cancel a fetch with a timeout
  • Pass AbortSignal to async APIs
  • Author cancelation-aware code

JavaScript’s standard cancellation primitive — same in browsers and Node. Create a controller, pass its signal around, call abort() to cancel everything tied to it.

The Basics

const ctrl = new AbortController();

const promise = fetch("https://example.com", { signal: ctrl.signal });

// somewhere else:
ctrl.abort();   // promise rejects with AbortError

A Timeout

Cancel a request after N ms:

const ctrl = new AbortController();
const timeout = setTimeout(() => ctrl.abort(), 5_000);

try {
  const res = await fetch("https://slow.api", { signal: ctrl.signal });
  return await res.json();
} catch (err) {
  if (err.name === "AbortError") {
    throw new Error("timed out");
  }
  throw err;
} finally {
  clearTimeout(timeout);
}

Shortcut: AbortSignal.timeout(ms) creates a signal that auto-aborts.

const res = await fetch(url, { signal: AbortSignal.timeout(5_000) });

Multiple Signals

Cancel when any of N signals fire:

const combined = AbortSignal.any([userCancel, timeoutSignal]);
await fetch(url, { signal: combined });

Pass-Through

Many Node APIs accept signals:

import { readFile } from "node:fs/promises";
import { setTimeout } from "node:timers/promises";

const ctrl = new AbortController();

await readFile("huge.txt", { signal: ctrl.signal });
await setTimeout(1000, undefined, { signal: ctrl.signal });

If ctrl.abort() fires while these are in flight, they reject.

Authoring Cancel-Aware Code

async function pollWith({ signal }) {
  while (true) {
    if (signal?.aborted) throw new Error("aborted");
    await doOneStep();
    await new Promise((r) => setTimeout(r, 1000));
  }
}

Always accept { signal } from callers — it’s the convention.

When to Use

  • Request timeouts
  • “User clicked cancel”
  • Stop a sub-task because its parent is going away

Once you have a function or pipeline that holds resources or runs indefinitely, an abort signal is the right API.

End of Chapter

That wraps the async core. Next chapter: HTTP — Node’s most popular use case.

HTTP Intro →