跳至主要內容

2637. 有时间限制的 Promise 对象


2637. 有时间限制的 Promise 对象open in new window

🟠   🔗 力扣open in new window LeetCodeopen in new window

题目

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 of t 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 1:

Input:

fn = async (n) => {

await new Promise(res => setTimeout(res, 100));

return n * n;

}

inputs = [5]

t = 50

Output:

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:

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:

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:

Explanation:

The function immediately throws an error.

Constraints:

  • 0 <= inputs.length <= 10
  • 0 <= t <= 1000
  • fn returns a promise

题目大意

请你编写一个函数,它接受一个异步函数 fn 和一个以毫秒为单位的时间 t。它应根据限时函数返回一个有 限时 效果的函数。函数 fn 接受提供给 限时 函数的参数。

限时 函数应遵循以下规则:

  • 如果 fnt 毫秒的时间限制内完成,限时 函数应返回结果。
  • 如果 fn 的执行超过时间限制,限时 函数应拒绝并返回字符串 "Time Limit Exceeded"

提示:

  • 0 <= inputs.length <= 10
  • 0 <= t <= 1000
  • fn 返回一个 Promise 对象

解题思路

  1. timeLimit 中返回了一个新的异步函数,并通过 Promise 来控制结果的返回。
  2. 设置一个定时器 setTimeout 用来判断 fn 是否超时,当超过给定的时间 t 时,定时器将触发,拒绝 Promise 并返回 "Time Limit Exceeded"
  3. 执行异步函数 fn,如果 fn 在规定时间内完成,无论是成功还是失败,都清理定时器以确保其不会再次执行。

复杂度分析

  • 时间复杂度:取决于传入的 fn 的复杂度,假设为 O(fn)
  • 空间复杂度O(1),仅有定时器和 Promise 相关的内存开销。

代码

/**
 * @param {Function} fn
 * @param {number} t
 * @return {Function}
 */
var timeLimit = function (fn, t) {
	return async function (...args) {
		return new Promise((resolve, reject) => {
			// 超时后拒绝 Promise
			const timer = setTimeout(() => reject('Time Limit Exceeded'), t);

			// 执行异步函数 fn
			fn(...args)
				.then((result) => {
					clearTimeout(timer); // 成功时清除定时器
					resolve(result);
				})
				.catch((err) => {
					clearTimeout(timer); // 失败时清除定时器
					reject(err);
				});
		});
	};
};

/**
 * const limited = timeLimit((t) => new Promise(res => setTimeout(res, t)), 100);
 * limited(150).catch(console.log) // "Time Limit Exceeded" at t=100ms
 */

相关题目

题号标题题解标签难度
2621睡眠函数open in new window[✓]
2622有时间限制的缓存open in new window[✓]
2627函数防抖open in new window[✓]
2636Promise 对象池 🔒open in new window[✓]
2676节流 🔒open in new window[✓]