What is the AbortController API and how is it used?
Assesses fundamental understanding of JavaScript conventions, runtime behavior, and memory/performance considerations.
Hiring managers look for precision, avoidance of ambiguous jargon, and ability to explain trade-offs under real production conditions.
The AbortController API provides a way to abort one or more asynchronous operations, particularly useful for canceling fetch requests.
Basic usage:
const controller = new AbortController();
const signal = controller.signal;
fetch('https://api.example.com/data', { signal })
.then(response => response.json())
.then(data => console.log(data))
.catch(err => {
if (err.name === 'AbortError') {
console.log('Fetch aborted');
}
});
// Cancel the request
controller.abort();
Timeout implementation:
function fetchWithTimeout(url, timeout = 5000) {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
return fetch(url, { signal: controller.signal })
.then(response => {
clearTimeout(timeoutId);
return response;
})
.catch(err => {
clearTimeout(timeoutId);
if (err.name === 'AbortError') {
throw new Error('Request timed out');
}
throw err;
});
}
fetchWithTimeout('https://api.example.com/slow-endpoint', 3000);
Canceling multiple requests:
const controller = new AbortController();
const signal = controller.signal;
Promise.all([
fetch('/api/users', { signal }),
fetch('/api/posts', { signal }),
fetch('/api/comments', { signal })
]).catch(err => {
if (err.name === 'AbortError') {
console.log('All requests aborted');
}
});
// Cancel all requests
controller.abort();
React component example:
useEffect(() => {
const controller = new AbortController();
async function fetchData() {
try {
const response = await fetch('/api/data', {
signal: controller.signal
});
const data = await response.json();
setData(data);
} catch (err) {
if (err.name !== 'AbortError') {
setError(err);
}
}
}
fetchData();
// Cleanup: abort on unmount
return () => controller.abort();
}, []);
Custom abortable operations:
function abortablePromise(promise, signal) {
return new Promise((resolve, reject) => {
signal.addEventListener('abort', () => {
reject(new DOMException('Aborted', 'AbortError'));
});
promise.then(resolve, reject);
});
}
const controller = new AbortController();
abortablePromise(
new Promise(resolve => setTimeout(resolve, 5000)),
controller.signal
).catch(err => console.log(err.name)); // 'AbortError'
controller.abort();
Candidate Response Strategy & Interview Tips
- Start with a concise one-sentence summary: Deliver a direct, confident answer first before expanding into nuances.
- Demonstrate real-world trade-offs: Discuss where this approach excels and when you would avoid it in production systems.
- Discuss complexity & edge cases: Proactively explain time/space complexity or boundary conditions (null values, scale limits).
- Prepare for interviewer follow-ups: Technical hiring panels frequently probe deeper into concurrency, backward compatibility, or alternative libraries.