Given an asynchronous function fn and a time t in milliseconds, return a new time limited version of the input function.
A time limited function is a function that is identical to the original unless it takes longer than t milliseconds to fullfill.
In that case, it will reject with “Time Limit Exceeded”.
Note that it should reject with a string, not an Error.
給予一個非同步的函式 fn 和一個以豪秒為單位的時間 t,回傳一個新的限時函式。 這個限時函式和原始函式完全相同,除非它超過 t 豪秒才能完成, 在這個情況下,它將拒絕並顯示“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}
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}
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}
Example 4:
Input: fn = async () => { throw "Error"; } inputs = [] t = 1000 Output: {"rejected":"Error","time":0}
solution:
以 Example 1 為例,呼叫 limited() 函式後,
進入到 timeLimit() 中建立一個含有 setTimeout() 的 new Promise(),
如果時間經過 t 豪秒後會執行 reject(“Time Limit Exceeded”)。
而 fn 函式放入 …args,並等待 100 豪秒後回傳 n * n,
此時因為超過 50 豪秒的時間限制,而 .catch(console.log) 抓取到 reject 的結果,
故回傳(“Time Limit Exceeded”)訊息。
ex.如果 fn(…args) 提前完成,則需取消 id 的限時函式。
Code 1: BigO(1)
var timeLimit = function(fn, t) { return async function(...args) { return new Promise((resolve, reject) => { const id = setTimeout(() => reject("Time Limit Exceeded"), t); fn(...args) .then((res) => resolve(res)) .catch((err) => reject(err)) .finally(() => clearTimeout(id)) }) } };
FlowChart:
Example 1
const limited = timeLimit(async (n) => { await new Promise((res) => setTimeout(res, 100)); return n * n; }, 50); limited(5).catch(console.log); // "Time Limit Exceeded" at t=50ms
Example 2
const limited = timeLimit(async (n) => { await new Promise((res) => setTimeout(res, 100)); return n * n; }, 150); limited(5).then(console.log).catch(console.log); // return 25 at t=100ms
Example 3
const limited = timeLimit(async (a, b) => { await new Promise((res) => setTimeout(res, 120)); return a + b; }, 150); limited(5, 10).then(console.log).catch(console.log); // return 15 at t=120ms
Example 4
const limited = timeLimit(async () => { throw "Error"; }, 1000); limited().then(console.log).catch(console.log); // "Error" at t=0ms