typescript 43 lines · 7 steps

Cancelling stale searches with AbortController

A search client that aborts the in-flight request whenever a newer query arrives, so only the latest result wins.

Explained by highlit
1type SearchResult = {
2 id: string;
3 title: string;
4};
5 
6export class SearchClient {
7 private controller: AbortController | null = null;
8 
9 async search(query: string): Promise<SearchResult[]> {
10 this.controller?.abort();
11 
12 const controller = new AbortController();
13 this.controller = controller;
14 
15 try {
16 const response = await fetch(
17 `/api/search?q=${encodeURIComponent(query)}`,
18 { signal: controller.signal },
19 );
20 
21 if (!response.ok) {
22 throw new Error(`Search failed with status ${response.status}`);
23 }
24 
25 const results = (await response.json()) as SearchResult[];
26 return results;
27 } catch (error) {
28 if (error instanceof DOMException && error.name === "AbortError") {
29 return [];
30 }
31 throw error;
32 } finally {
33 if (this.controller === controller) {
34 this.controller = null;
35 }
36 }
37 }
38 
39 cancel(): void {
40 this.controller?.abort();
41 this.controller = null;
42 }
43}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Storing the active AbortController as state lets a newer call cancel the previous one before it resolves.
  2. 2Distinguishing AbortError from real failures keeps intentional cancellations from surfacing as errors.
  3. 3A finally block that only clears state when the controller still matches avoids wiping out a newer request's controller.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Cancelling stale searches with AbortController — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code