A few years back I wrote a blog post about how write a fetch
Promise that times out. The function was effective but the code wasn’t great, mostly because AbortController
, which allows you to cancel a fetch Promise, did not yet exist. With AbortController
and AbortSignal
available, let’s create a better JavaScript function for fetching with a timeout:
Much like the original function, we’ll use setTimeout
to time to the cancellation but we’ll use the signal
with the fetch
request:
async function fetchWithTimeout(url, opts = {}, timeout = 5000) {
// Create the AbortController instance, get AbortSignal
const abortController = new AbortController();
const { signal } = abortController;
// Make the fetch request
const _fetchPromise = fetch(url, {
...opts,
signal,
});
// Start the timer
const timer = setTimeout(() => abortController.abort(), timeout);
// Await the fetch with a catch in case it's aborted which signals an error
try {
const result = await _fetchPromise;
clearTimeout(timer);
return result;
} catch (e) {
clearTimeout(timer);
throw e;
}
};
// Usage
try {
const impatientFetch = await fetchWithTimeout('/', {}, 2000);
}
catch(e) {
console.log("fetch possibly canceled!", e);
}
The JavaScript code above is much cleaner now that we have a proper API to cancel fetch
Promise calls. Attaching the signal
to the fetch request allows us to use a setTimeout
with abort
to cancel the request after a given amount of time.
It’s been excellent seeing AbortController
, AbortSignal
, and fetch
evolve to make async
requests more controllable without drastically changing the API.
The post fetch with Timeout appeared first on David Walsh Blog.