Skip to content
Async · Core · about 15 minutes

Promise with a timeout

Implement withTimeout(promise, ms). It returns a promise that settles as the given promise does when that happens within ms milliseconds, and otherwise rejects with new Error('Timeout'). When the promise settles first, clear your timer: the answer's leftover counts timers you left waiting and must be 0. In the tests a task [30, a] resolves with a after 30 ms and [30, boom, true] rejects with Error(boom); an outcome is [status, value, time].

Start from

function withTimeout(promise, ms) {
  // Settle like the promise, or reject with Error('Timeout') after ms.
}

Hints

Each hint gives away a little more. Open one only when you need it.

  1. Hint 1

    Return a new Promise. Start a timer that rejects, and forward the given promise's result with then.

  2. Hint 2

    A promise settles only once, so the loser is ignored. But keep the timer id and clear it in both then callbacks.

Solution

From here on the page gives the method away. If you are still solving, go back to the hints.

JavaScript
function withTimeout(promise, ms) {
  return new Promise((resolve, reject) => {
    const timer = setTimeout(() => reject(new Error("Timeout")), ms);
    promise.then(
      (value) => {
        clearTimeout(timer);
        resolve(value);
      },
      (error) => {
        clearTimeout(timer);
        reject(error);
      },
    );
  });
}

What an interviewer looks for

Every network call needs a time limit. Interviewers look for the cleanup, and often ask how you would also cancel the request itself (AbortController).