How can we timeout a promise?

javascript-promises

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
})
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License