https://italonascimento.github.io/applying-a-timeout-to-your-promises/ - done reading
Sometimes a promise may take too long to resolve or reject, and sometimes we just can't wait for it. We can apply a timeout to a promise using Promise.race(). The Promise.race(iterable) method returns a promise that resolves or rejects as soon as one of the promises in the iterable resolves or rejects, with the value or reason from that promise.
const promiseTimeout = function(ms, promise){
// Create a promise that rejects in <ms> milliseconds
let timeout = new Promise((resolve, reject) => {
let id = setTimeout(() => {
clearTimeout(id);
reject('Timed out in '+ ms + 'ms.')
}, ms)
})
// Returns a race between our timeout and the passed in promise
return Promise.race([
promise,
timeout
])
}
In the above code, we created the promiseTimeout function, which takes two parameters, a timeout in milliseconds, and an existing promise, and returns a race between the passed in and a locally defined promise, called timeout. The timeout promise, in turn, does nothing but reject in ms milliseconds.
Promise.race will give us a new promise that gets resolved or rejected as soon as any of the provided promises resolve or reject.
To easily use our new function in a real project, let’s first export it as a module by adding the export default keywords and saving as timeout-promise.js.
export default const promiseTimeout = function(ms, promise){
// Create a promise that rejects in <ms> milliseconds
let timeout = new Promise((resolve, reject) => {
let id = setTimeout(() => {
clearTimeout(id);
reject('Timed out in '+ ms + 'ms.')
}, ms)
})
// Returns a race between our timeout and the passed in promise
return Promise.race([
promise,
timeout
])
}
Now, by importing timeoutPromise and passing doSomething() as a parameter to it (instead of calling it directly), we’re able to specify a timeout to doSomething even if we don’t have access to it’s source.
import timeoutPromise from './timeout-promise';
const doSomething = function(){
return new Promise((resolve, reject) => {
/* ... */
})
};
// Apply a timeout of 5 seconds to doSomething
let doIt = timeoutPromise(5000, doSomething())
// Wait for the promise to get resolved
doIt.then(response => {
// Use response
})
// Wait for the promise to get rejected or timed out
doIt.catch(error => {
// Deal with error
})