LeetCode 题解工作台

执行可取消的延迟函数

给定一个函数 fn ,一个参数数组 args 和一个以毫秒为单位的超时时间 t ,返回一个取消函数 cancelFn 。 在 cancelTimeMs 的延迟后,返回的取消函数 cancelFn 将被调用。 setTimeout(cancelFn, cancelTimeMs) 最初,函数 fn 的执…

category

0

题型

code_blocks

2

代码语言

hub

0

相关题

当前训练重点

简单 · Timeout Cancellation core interview pattern

bolt

答案摘要

function cancellable(fn: Function, args: any[], t: number): Function { const timer = setTimeout(() => fn(...args), t);

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 Timeout Cancellation core interview pattern 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

给定一个函数 fn ,一个参数数组 args 和一个以毫秒为单位的超时时间 t ,返回一个取消函数 cancelFn

cancelTimeMs 的延迟后,返回的取消函数 cancelFn 将被调用。

setTimeout(cancelFn, cancelTimeMs)

最初,函数 fn 的执行应该延迟 t 毫秒。

如果在 t 毫秒的延迟之前调用了函数 cancelFn,它应该取消 fn 的延迟执行。否则,如果在指定的延迟 t 内没有调用 cancelFn,则应执行 fn,并使用提供的 args 作为参数。

 

示例 1:

输入:fn = (x) => x * 5, args = [2], t = 20
输出:[{"time": 20, "returned": 10}]
解释:
const cancelTimeMs = 50;
const cancelFn = cancellable((x) => x * 5, [2], 20);
setTimeout(cancelFn, cancelTimeMs);

取消操作被安排在延迟了 cancelTimeMs(50毫秒)后进行,这发生在 fn(2) 在20毫秒时执行之后。

示例 2:

输入:fn = (x) => x**2, args = [2], t = 100
输出:[]
解释:
const cancelTimeMs = 50;
const cancelFn = cancellable((x) => x**2, [2], 100);
setTimeout(cancelFn, cancelTimeMs);

取消操作被安排在延迟了 cancelTimeMs(50毫秒)后进行,这发生在 fn(2) 在100毫秒时执行之前,导致 fn(2) 从未被调用。

示例 3:

输入:fn = (x1, x2) => x1 * x2, args = [2,4], t = 30
输出:[{"time": 30, "returned": 8}]
解释:
const cancelTimeMs = 100;
const cancelFn = cancellable((x1, x2) => x1 * x2, [2,4], 30);
setTimeout(cancelFn, cancelTimeMs);

取消操作被安排在延迟了 cancelTimeMs(100毫秒)后进行,这发生在 fn(2,4) 在30毫秒时执行之后。

 

提示:

  • fn 是一个函数
  • args 是一个有效的 JSON 数组
  • 1 <= args.length <= 10
  • 20 <= t <= 1000
  • 10 <= cancelTimeMs <= 1000
lightbulb

解题思路

方法一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
 * @param {Function} fn
 * @param {Array} args
 * @param {number} t
 * @return {Function}
 */
var cancellable = function (fn, args, t) {
    const timer = setTimeout(() => fn(...args), t);
    return () => {
        clearTimeout(timer);
    };
};

/**
 *  const result = []
 *
 *  const fn = (x) => x * 5
 *  const args = [2], t = 20, cancelT = 50
 *
 *  const start = performance.now()
 *
 *  const log = (...argsArr) => {
 *      const diff = Math.floor(performance.now() - start);
 *      result.push({"time": diff, "returned": fn(...argsArr))
 *  }
 *
 *  const cancel = cancellable(log, args, t);
 *
 *  const maxT = Math.max(t, cancelT)
 *
 *  setTimeout(() => {
 *     cancel()
 *  }, cancelT)
 *
 *  setTimeout(() => {
 *     console.log(result) // [{"time":20,"returned":10}]
 *  }, maxT + 15)
 */
speed

复杂度分析

指标
时间**
空间**
psychology

面试官常问的追问

外企场景
  • question_mark

    The candidate should demonstrate an understanding of `setTimeout` and timing functions.

  • question_mark

    Look for an efficient approach to canceling execution without unnecessary delays.

  • question_mark

    Check if the candidate correctly handles edge cases, such as the cancel function being invoked after the timeout has expired.

warning

常见陷阱

外企场景
  • error

    Failing to handle the cancel function being invoked after `t` has already expired.

  • error

    Incorrectly managing the timing of the cancel function, causing unexpected behavior.

  • error

    Not ensuring that `cancelFn` is invoked only once and that `fn` is not called multiple times.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Implement the solution using promises instead of callbacks.

  • arrow_right_alt

    Extend the problem to support multiple cancel functions, each for different timeouts.

  • arrow_right_alt

    Add a feature to allow cancellation after multiple delays.

help

常见问题

外企场景

执行可取消的延迟函数题解:Timeout Cancellation co… | LeetCode #2715 简单