JavaScript fetch with Timeout

The fetch API started out as a target for criticism because of lack of timeout and request cancelation.  While those criticisms could be argued as fair or not, you can’t deny that the fetch API has been pretty awesome.  As we’ve always done, if a feature is missing, we can always shim it in.

I’ve recently been thinking about shimming in a fetch timeout and found a good fetch / timeout script here.  I’ve slightly modified it to prevent the fetch call’s then and catch callbacks from carrying out their tasks because I believe the timeout should be handled by the shim’s Promise:

const FETCH_TIMEOUT = 5000;
let didTimeOut = false; new Promise(function(resolve, reject) { const timeout = setTimeout(function() { didTimeOut = true; reject(new Error('Request timed out')); }, FETCH_TIMEOUT); fetch('https://davidwalsh.name/?xx1') .then(function(response) { // Clear the timeout as cleanup clearTimeout(timeout); if(!didTimeOut) { console.log('fetch good! ', response); resolve(response); } }) .catch(function(err) { console.log('fetch failed! ', err); // Rejection already happened with setTimeout if(didTimeOut) return; // Reject with error reject(err); });
})
.then(function() { // Request success and no timeout console.log('good promise, no timeout! ');
})
.catch(function(err) { // Error: response error, request timeout or runtime error console.log('promise error! ', err);
});

Wrapping this code in a function called fetchWithTimeout, whereby you pass in a timeout and fetch URL/settings would work well; since people like to use fetch in a variety of ways, I’ve chosen not to create a generalized function and instead am just providing the basic logic.

Many would argue that the timeout should come from the server but we all know us front-end devs don’t always have control over both sides of a request.  If you’re looking for a fetch request timeout snippet, here you go!

Related Post

Rojenx is a leading concept artist who work appears in games and publications

Check out his personal gallery here

In other news …