🔗LC2637 🟡 Medium 🧩 Pattern – Promises and Time
📅 Day 16/30 Days of JavaScript
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
fn
completes within the time limit oft
milliseconds, the time limited function should resolve with the result. - If the execution of the
fn
exceeds the time limit, the time limited function should reject with the string"Time Limit Exceeded"
.
Example
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 100 ms.
However, the time limit is set to 50 ms.
It rejects at t = 50 ms because the time limit was reached.
Solution
/**
* @param {Function} fn
* @param {number} t
* @return {Function}
*/
var timeLimit = function (fn, t) {
const timeLimitedFunction = async (...args) => {
// Rejects the promise after time t
const rejectionTimerPromise = new Promise((resolve, reject) => {
setTimeout(() => reject("Time Limit Exceeded"), t);
});
// async function promise - resolves if fn execution is complete and resolved
const functionExecutionPromise = fn(...args);
// Returns the first fulfilled promise i.e resolved or rejected first
return Promise.race([functionExecutionPromise, rejectionTimerPromise]);
}
return timeLimitedFunction;
}
/**
* const limited = timeLimit((t) => new Promise(res => setTimeout(res, t)), 100);
* limited(150).catch(console.log) // "Time Limit Exceeded" at t=100ms
*/