DEV Community

Hanan Hamza
Hanan Hamza

Posted on

Implement Request Timeout Using Fetch and AbortController

consider this, you have a web-app that requests some data from some external service and you want to cancel the request if it takes more than n seconds. how would you implement this using javascript? I got you

this is the final snippet that you could modify according to your needs:

(async () => {

// we'll use to add dely/sleep logic
const timedOut = Symbol("Timeout")
const sleep= (delay) => new Promise((resolve, reject) => {
  setTimeout(resolve, delay, timedOut);
});

// the actual interface that we'd be using to cancel the request
const abortController = new AbortController();
const signal = abortController.signal;

// this is our external api call
// delay is added only to mock time-taking requests
const getData =async (signal,delay) => {
await sleep(delay)
return fetch("https://jsonplaceholder.typicode.com/todos/1",{
  signal
})
}

// promise.race returns whichever promise resolves first
const res = await Promise.race([
  sleep(3000),
  getData(signal,3000)
]);

// if response is timeout abort the request
if(res === timedOut) {
  abortController.abort();
} else {
  // do whatever you want to do with the result
}
})()
Enter fullscreen mode Exit fullscreen mode

lets walk through the code bit by bit

const timedOut = Symbol("Timeout")
const sleep= (delay) => new Promise((resolve, reject) => {
  setTimeout(resolve, delay, timedOut);
});
Enter fullscreen mode Exit fullscreen mode

this code resolves after however much delay we provide it with value of the symbol timedOut which we'll use later

const abortController = new AbortController();
const signal = abortController.signal;
Enter fullscreen mode Exit fullscreen mode

this is the interface that allows us to cancel one or more webRequests that use the same signal

const res = await Promise.race([
  sleep(3000),
  getData(signal,3000)
]);

// if response is timeout abort the request
if(res === timedOut) {
  abortController.abort();
} else {
  // do whatever you want to do with the result
}
Enter fullscreen mode Exit fullscreen mode

The Promise.race() method returns a promise that fulfills or rejects as soon as one of the promises in an iterable fulfills or rejects, with the value or reason from that promise.

in our case, if the request takes more time than the timeout specified; sleep() function will resolve first and we can compare the response to abort the request.

That's all folks! :)

Top comments (0)