Problem
Given an asynchronous function fn and a time t in milliseconds, return a new time limited version of the input function. fn takes arguments provided to the time limited function.
The time limited function should follow these rules:
- If the
fncompletes within the time limit oftmilliseconds, the time limited function should resolve with the result. - If the execution of the
fnexceeds the time limit, the time limited function should reject with the string"Time Limit Exceeded".
Example 1:
Input: fn = async (n) => { await new Promise(res => setTimeout(res, 100)); return n * n; },
inputs = [5], t = 50
Output: { rejected: "Time Limit Exceeded", time: 50 }
Solution
Promise.race resolves or rejects with whichever promise settles first. So we race the real work against a “timer” promise that rejects after t milliseconds: if fn finishes first, we get its result; if the timer fires first, we get the rejection.
var timeLimit = function (fn, t) {
return async function (...args) {
return Promise.race([
fn(...args),
new Promise((_, reject) =>
setTimeout(() => reject("Time Limit Exceeded"), t),
),
]);
};
};
Complexity Analysis
| Measure | Complexity |
|---|---|
| Time Complexity | O(1) |
| Space Complexity | O(1) |
- The wrapper only adds one extra promise and one timer per call
Notes
Promise.racedoes not cancel the losing promise: if the timer wins,fnkeeps running in the background; its result is just ignored. Real cancellation would need something likeAbortController.- The timer promise never resolves, it only rejects, so it can never accidentally “win” with a value.
- Classic pattern for wrapping APIs that may hang: timeouts on fetch calls, database queries, etc.