Frontend Labs
⋯

27. fetch and XMLHttpRequest: requests, streaming, aborting

fetch() is promise-based and the modern default; XMLHttpRequest (XHR) predates promises and is still relevant for upload progress events, which fetch didn't support natively until ReadableStream request bodies matured.

// Aborting an in-flight fetch — critical for search-as-you-type, tab switches, etc.
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);   // 5s timeout

try {
  const res = await fetch("/api/search?q=js", { signal: controller.signal });
  clearTimeout(timeoutId);
  const data = await res.json();
} catch (err) {
  if (err.name === "AbortError") console.log("Request timed out or was cancelled");
  else throw err;
}

Streaming a response body — process data as it arrives instead of waiting for the whole payload (large JSON, NDJSON logs, LLM token streams):

const res = await fetch("/api/stream");
const reader = res.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  console.log("chunk:", decoder.decode(value, { stream: true }));
}

Generated from real-life-JS-guide.md · 8 Oct 2026 16:36