Whenever a Promise request happens, it is common for it to have a timeout. If the time limit is exceeded, it'll cancel the request and throw a timeout error.
How would you implement that fallback? Do you use setTimeout
? Or, at worst, do you use performance.now
to calculate whether the request exceeded the time limit?
This is where Promise.race
comes in. According to MDN:
The
Promise.race()
static method takes an iterable of promises as input and returns a singlePromise
.
As the name suggests, it triggers the iterable (such as an Array) of Promise
objects, and whichever resolves the fastest will be returned.
So, using Promise.race
, you can implement a time limit fallback with minimal code.
// Where fn is the promise, and
// ms is the time limit in milliseconds
function timeLimit(fn, ms) {
const fallback = new Promise((_, reject) => {
setTimeout(() => {
reject("Time limit exceeded");
}, ms);
});
return Promise.race([fn, fallback]);
}
This function simultaneously executes the fn
argument and the fallback
promise. The fallback
promise creates a timeout with ms
as the delay time. Therefore, it rejects the promise after the delay time.
Since Promise.race
returns the first promise to finish, the "Time limit exceeded"
rejection can be returned if the fn
promise is late.
Conversely, if fn
finishes earlier, it will return its result, either resolved or rejected.
That's it. Thank you for reading! Would you mind giving this post a reaction?
Top comments (1)
I also used Promise.race to add timeouts to fetch calls.