Promise Time Limit
MediumUpdated: Aug 2, 2025
Practice on:
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".
Examples
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}
Explanation:
const limited = timeLimit(fn, t)
const start = performance.now()
let result;
try {
const res = await limited(...inputs)
result = {"resolved": res, "time": Math.floor(performance.now() - start)};
} catch (err) {
result = {"rejected": err, "time": Math.floor(performance.now() - start)};
}
console.log(result) // Output
The provided function is set to resolve after 100ms. However, the time limit is set to 50ms. It rejects at t=50ms because the time limit was reached.
Example 2
Input:
fn = async (n) => {
await new Promise(res => setTimeout(res, 100));
return n * n;
}
inputs = [5]
t = 150
Output: {"resolved":25,"time":100}
Explanation:
The function resolved 5 * 5 = 25 at t=100ms. The time limit is never reached.
Example 3
Input:
fn = async (a, b) => {
await new Promise(res => setTimeout(res, 120));
return a + b;
}
inputs = [5,10]
t = 150
Output: {"resolved":15,"time":120}
Explanation:
The function resolved 5 + 10 = 15 at t=120ms. The time limit is never reached.
#### Example 4
Input:
fn = async () => {
throw "Error";
}
inputs = []
t = 1000
Output: {"rejected":"Error","time":0}
Explanation:
The function immediately throws an error.
Constraints
0 <= inputs.length <= 100 <= t <= 1000fnreturns a promise
Solution
Method 1 – Promise.race with Timeout
Intuition
We want to run the original async function, but if it takes longer than t milliseconds, we should reject with "Time Limit Exceeded". This is a classic use case for Promise.race, where we race the original promise against a timeout promise.
Approach
- Return a new function that, when called, returns a
Promise. - Start the original function and a timeout promise in parallel.
- If the original function resolves or rejects before the timeout, propagate its result.
- If the timeout fires first, reject with the required message.
Code
JavaScript
/**
* @param {Function} fn
* @param {number} t
* @return {Function}
*/
var timeLimit = function(fn, t) {
return async function(...args) {
return Promise.race([
fn(...args),
new Promise((_, reject) => setTimeout(() => reject("Time Limit Exceeded"), t))
]);
}
};
TypeScript
function timeLimit<T extends (...args: any[]) => Promise<any>>(fn: T, t: number): (...args: Parameters<T>) => Promise<ReturnType<T> extends Promise<infer R> ? R : never> {
return async (...args: Parameters<T>) => {
return Promise.race([
fn(...args),
new Promise((_, reject) => setTimeout(() => reject("Time Limit Exceeded"), t))
]) as any;
};
}
Complexity
- ⏰ Time complexity:
O(1)for the wrapper, plus the time taken by the original function. - 🧺 Space complexity:
O(1)for the wrapper.