FSM Full Stack Masterclass
Platform under construction
JavaScript course badge

Async JavaScript

Advanced

AbortController & Streams

AbortController cancels async work. Streams let code process data in chunks instead of waiting for everything at once.

const controller = new AbortController();

fetch(url, { signal: controller.signal });
controller.abort();

Async JavaScript

Cancellation and streaming make async work more controllable.

AbortController creates a signal that can be passed to APIs such as fetch and addEventListener. Calling abort notifies those APIs that the work should stop.

Cancellation matters when users navigate away, type a new query or close a panel before async work finishes.

Streams represent data arriving over time. They are useful for large responses, progressive processing and advanced performance work.

AbortController

Creates a cancellation signal.

AbortSignal

Passed to APIs that support cancellation.

abort

Triggers cancellation.

Streams

Process data chunk by chunk.

Examples

Async code should show state, handle failure and avoid stale results.

Cancel work when it is no longer relevant

const controller = new AbortController();

startButton.addEventListener("click", () => runTask(controller.signal));
stopButton.addEventListener("click", () => controller.abort());

Letting stale async work update the UI

const data = await fetchResults(query);
render(data);

// A slower old query can overwrite a newer result.

Code patterns

Reusable examples for quick reference.

These examples are the async patterns you will reuse: timers, promises, composition, await, fetch and cancellation.

Abort fetch

Pass signal to fetch.

const controller = new AbortController();
const response = await fetch(url, { signal: controller.signal });
controller.abort();

Detect abort error

Abort usually rejects with AbortError.

try {
  await fetch(url, { signal });
} catch (error) {
  if (error.name === "AbortError") return;
}

Listener cleanup

Use signal to remove listeners automatically.

element.addEventListener("click", handler, { signal });
controller.abort();

Read stream

Streams expose a reader for chunks.

const reader = response.body.getReader();
const { value, done } = await reader.read();

Rules that matter

Make time visible in your code.

Async JavaScript is easier when every operation has clear pending, success, failure and cancellation behavior.

Cancel stale work

Old requests should not overwrite newer UI.

Pass the signal early

APIs need the signal before work starts.

Handle AbortError separately

Cancellation is often expected, not a failure message.

Use signals for listener cleanup

AbortController can clean temporary listeners.

Use streams for large data

Do not load huge bodies into memory unnecessarily.

Keep cancellation state clear

The UI should know whether work finished, failed or was cancelled.

Production thinking

Reliable async code is what makes modern interfaces feel fast instead of fragile.

Why does this matter?

Without cancellation, async interfaces can show stale results and waste resources.

Accessibility

Cancelled loading should leave users with a clear state, not an endless busy message.

Production note

Production search, upload and navigation flows often need cancellation to avoid race conditions.

SEO note

Cancellation is mostly runtime behavior, but stale async rendering can produce confusing page states.

Live code lab

Change the HTML, CSS or JavaScript and run the result.

The preview runs inside an isolated iframe. The JavaScript is placed inside the HTML editor for now, so every example stays together and remains easy to understand.

Mini assignment

Try this now.

  • Disable the start button while work is running.
  • Start a new controller for every new task.
  • Ignore AbortError in the catch block and compare the UI.

Practice assignment

Do this before moving to the next topic.

  1. Create an AbortController.
  2. Pass signal into async work.
  3. Handle cancellation separately from failure.

Try it yourself

Cancel an async task

Live preview

Self-check

Before you continue, prove that you understand AbortController & Streams.

Advanced

If you can explain when the code runs, how it fails and what happens if it becomes irrelevant, you understand the async model.

  1. Can you explain AbortController?
  2. Can you explain AbortSignal?
  3. Can you explain AbortError?
  4. Can you explain stale async results?
  5. Can you explain what streams are for?

Chapter checkpoint

Async JavaScript checkpoint

Finish this chapter by turning the lessons into a small practical proof.

Build

Create a mock fetch flow with loading, success, error and abort behavior.

Deliverables

  • loading state
  • error state
  • success render
  • cancellation note

Quality checks

  • response errors handled
  • race conditions considered
  • UI never stays stuck loading

Review question

What happens if the request fails twice in a row?