Async & Promisesmedium

Wrap a promise with timeout

Implement `withTimeout(promise, ms)` that rejects with a timeout error if the original promise does not settle in time.

Asked at Amazon, Google, Netflix

#promises#timeout#error handling

Answer

function withTimeout(promise, ms, message = 'Operation timed out') {
  return new Promise((resolve, reject) => {
    const timer = setTimeout(() => {
      reject(new Error(message))
    }, ms)

    Promise.resolve(promise)
      .then((value) => {
        clearTimeout(timer)
        resolve(value)
      })
      .catch((err) => {
        clearTimeout(timer)
        reject(err)
      })
  })
}

// Usage
withTimeout(new Promise((res) => setTimeout(() => res('ok'), 30)), 100)
  .then(console.log) // ok

withTimeout(new Promise((res) => setTimeout(() => res('late'), 200)), 50)
  .catch((e) => console.error(e.message)) // Operation timed out

Practise more Async & Promises questions →