How do you cancel pending fetches using AbortController?

Async cancellation and race-condition prevention in UI streams.
Keep one AbortController, abort before each fetch, pass its signal, and swallow AbortError.
Forgetting prior abort or leaving rejections uncaught.
What's really being asked
This question probes your ability to manage asynchronous side effects in user-driven event streams. Interviewers want to see that you understand the AbortController API, can prevent race conditions where an older fetch resolves after a newer one, and know how to handle the specific promise rejection that aborting produces. It also surfaces whether you think about memory leaks and network efficiency in production UI code.
The full answer
First, declare a mutable variable outside the handler to hold the current AbortController instance. Second, inside the search handler, check if a controller exists and call abort() on it before creating a new one. Third, instantiate a fresh AbortController and assign it to that variable. Fourth, pass controller.signal into the fetch options object as the signal property. Fifth, wrap the fetch call in a try-catch block and suppress the AbortError by checking if error.name equals AbortError so you do not log spurious failures. Sixth, mention that aborting triggers a DOMException with name AbortError and that fetch promises reject with it.
The mistakes people make
A major red flag is suggesting debounce alone without cancellation, because a 300 millisecond debounce still leaves a window where rapid typing can overlap requests. Another mistake is calling abort() without catching the resulting exception, which creates unhandled promise rejections. Some candidates propose a global flag like isLoading and ignoring responses, which prevents stale data but wastes bandwidth and server resources. Storing the controller in React state instead of a ref or closure variable is also wrong because state updates are asynchronous and batched, so you might abort the wrong request or trigger extra renders.
What usually comes next
The interviewer might ask how you would handle this in React specifically, where you should store the controller in a useRef to avoid re-renders and clean it up in a useEffect return function on component unmount. They might also ask what happens if you abort after the fetch has already completed, which is safe and simply a no-op. Another variant is asking how to cancel multiple in-flight requests at once, where you would keep an array of controllers and abort each one. You might also be asked to compare AbortController against Axios cancel tokens or against simply ignoring stale responses.
A concrete example
Imagine a search box firing on every keystroke. Without cancellation, typing abc quickly initiates three requests. If the a query is slow and resolves after c, the UI flashes the wrong results. With AbortController, on the b keystroke you abort the a request, and on c you abort b. The browser cancels the TCP connection or stops processing the response, saving roughly 100 to 500 milliseconds of wasted network time per skipped request depending on payload size. Your catch block silently discards the AbortError, and only the c response renders.
Interview question
When wiring AbortController to a rapid-type search input, which pattern prevents stale UI results without producing unhandled promise rejections?
- a.Reuse a single AbortController across all fetches, calling abort() before each request to reset the signal
- b.Debounce keystrokes by 300 ms and skip cancellation because the delay eliminates overlapping requests
- c.Store the controller in React state and abort the previous instance whenever the input changes
- d.Call abort() on the prior controller if it exists, then instantiate a fresh one and pass its signal to fetch, catching only errors named AbortErrorCorrect
Why? this is the answer
You must abort the prior controller before creating a fresh one, pass its signal, and suppress only AbortError to avoid unhandled rejections. Reusing the same controller is tempting but wrong because an aborted signal never resets, so subsequent fetches would abort immediately.
Just read this? Test yourself on what you have been reading.
Read the original → developer.mozilla.org
- #abortcontroller
- #fetch
- #race-conditions
- #typescript
- #async
You just looked this up. Could you explain it out loud?
That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Every open role lists the topics its interview covers, so you can prepare for the real thing rather than guessing.
See open roles