2725. 间隔取消

简介: 2725. 间隔取消

说在前面

🎈不知道大家对于算法的学习是一个怎样的心态呢?为了面试还是因为兴趣?不管是出于什么原因,算法学习需要持续保持。

题目描述

现给定一个函数 fn,一个参数数组 args 和一个时间间隔 t,返回一个取消函数 cancelFn。

在经过 cancelTimeMs 毫秒的延迟后,将调用返回的取消函数 cancelFn。

setTimeout(cancelFn, cancelTimeMs)

函数 fn 应立即使用参数 args 调用,然后每隔 t 毫秒调用一次,直到在 cancelTimeMs 毫秒时调用 cancelFn。

示例 1:

输入:fn = (x) => x * 2, args = [4], t = 35, cancelT = 190
输出:
[
   {"time": 0, "returned": 8},
   {"time": 35, "returned": 8},
   {"time": 70, "returned": 8},
   {"time": 105, "returned": 8},
   {"time": 140, "returned": 8},
   {"time": 175, "returned": 8}
]
解释: 
const cancelTimeMs = 190;
const cancelFn = cancellable((x) => x * 2, [4], 35);
setTimeout(cancelFn, cancelTimeMs);
每隔 35ms,调用 fn(4)。直到 t=190ms,然后取消。
第一次调用 fn 是在 0ms。fn(4) 返回 8。
第二次调用 fn 是在 35ms。fn(4) 返回 8。
第三次调用 fn 是在 70ms。fn(4) 返回 8。
第四次调用 fn 是在 105ms。fn(4) 返回 8。
第五次调用 fn 是在 140ms。fn(4) 返回 8。
第六次调用 fn 是在 175ms。fn(4) 返回 8。
在 t=190ms 时取消

示例 2:

输入:fn = (x1, x2) => (x1 * x2), args = [2, 5], t = 30, cancelT = 165
输出: 
[
   {"time": 0, "returned": 10},
   {"time": 30, "returned": 10},
   {"time": 60, "returned": 10},
   {"time": 90, "returned": 10},
   {"time": 120, "returned": 10},
   {"time": 150, "returned": 10}
]
解释:
const cancelTimeMs = 165; 
const cancelFn = cancellable((x1, x2) => (x1 * x2), [2, 5], 30) 
setTimeout(cancelFn, cancelTimeMs)
每隔 30ms,调用 fn(2, 5)。直到 t=165ms,然后取消。
第一次调用 fn 是在 0ms
第二次调用 fn 是在 30ms
第三次调用 fn 是在 60ms
第四次调用 fn 是在 90ms
第五次调用 fn 是在 120ms
第六次调用 fn 是在 150ms
在 165ms 取消

示例 3:

输入:fn = (x1, x2, x3) => (x1 + x2 + x3), args = [5, 1, 3], t = 50, cancelT = 180
输出:
[
   {"time": 0, "returned": 9},
   {"time": 50, "returned": 9},
   {"time": 100, "returned": 9},
   {"time": 150, "returned": 9}
]
解释:
const cancelTimeMs = 180;
const cancelFn = cancellable((x1, x2, x3) => (x1 + x2 + x3), [5, 1, 3], 50)
setTimeout(cancelFn, cancelTimeMs)
每隔 50ms,调用 fn(5, 1, 3)。直到 t=180ms,然后取消。
第一次调用 fn 是在 0ms
第二次调用 fn 是在 50ms
第三次调用 fn 是在 100ms
第四次调用 fn 是在 150ms
在 180ms 取消

提示:

  • fn 是一个函数
  • args 是一个有效的 JSON 数组
  • 1 <= args.length <= 10
  • 30 <= t <= 100
  • 10 <= cancelT <= 500

解题思路

  • 1、调用 fn 函数并传入参数数组 args,以初始化结果。
  • 2、使用 setInterval 创建定时器,并在每次触发时调用 fn 函数并传入参数数组 args。
  • 3、返回一个无参数的函数,用于清除定时器。
  • 4、在外部使用返回的函数即可取消定时器。

实际使用示例中,代码定义了一个辅助函数 log,用于记录每次执行 fn 函数的返回值,并添加时间戳记录。然后使用 cancellable 函数将 log 函数包裹起来,创建一个可取消的定时任务。在定时任务结束后,输出记录结果。

AC代码

/**
 * @param {Function} fn
 * @param {Array} args
 * @param {number} t
 * @return {Function}
 */
var cancellable = function(fn, args, t) {
    fn(...args);
    const timer = setInterval(()=>{
        fn(...args);
    },t);
    return ()=>{clearInterval(timer)};
};
/**
 *  const result = [];
 *
 *  const fn = (x) => x * 2;
 *  const args = [4], t = 35, cancelTimeMs = 190;
 *
 *  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);
 *
 *  setTimeout(cancel, cancelTimeMs);
 *   
 *  setTimeout(() => {
 *      console.log(result); // [
 *                           //     {"time":0,"returned":8},
 *                           //     {"time":35,"returned":8},
 *                           //     {"time":70,"returned":8},
 *                           //     {"time":105,"returned":8},
 *                           //     {"time":140,"returned":8},
 *                           //     {"time":175,"returned":8}
 *                           // ]
 *  }, cancelTimeMs + t + 15)    
 */

公众号

关注公众号『前端也能这么有趣』,获取更多有趣内容。

说在后面

🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,偶尔也会在自己的公众号『前端也能这么有趣』发一些比较有趣的文章,有兴趣的也可以关注下。在此谢谢大家的支持,我们下文再见 🙌。

目录
相关文章
|
6月前
|
JavaScript
弹框下次触发时还保留上次的触发条件
弹框下次触发时还保留上次的触发条件
|
6月前
|
算法 前端开发
3019. 按键变更的次数
3019. 按键变更的次数
35 0
|
1月前
定时器 在某个时间到达之后,执行指定的任务
本文介绍了两种实现定时器的方法:基于优先级队列(堆)和基于时间轮,以在指定时间到达后执行特定任务。
33 0
定时器 在某个时间到达之后,执行指定的任务
|
6月前
|
JSON 前端开发 算法
2715. 执行可取消的延迟函数
2715. 执行可取消的延迟函数
41 0
|
11月前
|
NoSQL Java 调度
订单超时取消的11种方法(下)
大家好,我是三友~~ 延迟任务在我们日常生活中比较常见,比如订单支付超时取消订单功能,又比如自动确定收货的功能等等。 所以本篇文章就来从实现到原理来盘点延迟任务的11种实现方式,这些方式并没有绝对的好坏之分,只是适用场景的不大相同。
订单超时取消的11种方法(下)
|
11月前
|
消息中间件 NoSQL Java
订单超时取消的11种方法(上)
大家好,我是三友~~ 延迟任务在我们日常生活中比较常见,比如订单支付超时取消订单功能,又比如自动确定收货的功能等等。 所以本篇文章就来从实现到原理来盘点延迟任务的11种实现方式,这些方式并没有绝对的好坏之分,只是适用场景
订单超时取消的11种方法(上)
|
JavaScript 前端开发
JavaScript时间戳获取及时间戳判断(同时设置不同的颜色。已开始的事件显示绿色,未开始的事件显示黑色,过去的事件显示灰色)
JavaScript时间戳获取及时间戳判断(同时设置不同的颜色。已开始的事件显示绿色,未开始的事件显示黑色,过去的事件显示灰色)
95 0
|
JavaScript 前端开发
JavaScript实现显示时间,暂停时间,和取消显示时间
JavaScript实现显示时间,暂停时间,和取消显示时间
|
JavaScript 前端开发
一个按钮控制定时器的开始与暂停
一个按钮控制定时器的开始与暂停
一个按钮控制定时器的开始与暂停
|
Windows 搜索推荐 开发者