用 React 封装一个可暂停并保留剩余倒计时的计时器钩子 | 您所在的位置:网站首页 › js如何实现倒计时秒 › 用 React 封装一个可暂停并保留剩余倒计时的计时器钩子 |
我正在参加「掘金·启航计划」 useKeepInterval我们一般会使用 setTimeout 和 setInterval 用来做倒计时和计时的操作,而如果我想要暂停这个操作就需要执行 clearTimeout 和 clearInterval, 但是如果我想要基于上一次暂停的剩余时间,继续开始倒计时,这就需要再进一步的处理了。 因此这个可以(暂停 / 继续)并保留剩余倒计时的计时器钩子就诞生了。 源码 使用文档 demo预览 实现过程 数据定义定义一个 useRef 其中保存以下数据。 timeout: 用于保存最外层的 setTimeout interval: 保存的内层的 setInterval cur: 记录当前时间 end: 记录暂停时间 fn: 传入的执行函数 intervalTime: 固定的时间间隔 remainTime: 用于 setTimeout 的剩余时间间隔 const timerRef = useRef({ timeout: null, interval: null, cur: 0, end: 0, fn: undefined, intervalTime: 0, remainTime: 0 }) 开始计时器传入执行函数,间隔时间,即可开始一个根据倒计时运行的函数(中途可以暂停和继续)。 实现过程主要是将传递进来的函数,间隔时间等记录下来,然后通过一个 setTimeout 包裹住 setInterval 并在其中穿插执行函数,同时需要记录并处理开始暂停等操作的时间即可。 /** * 设置/开启计时器 * @param fn 执行函数 * @param intervalTime 间隔时间 * @param isInit 是否是初始化设置计时器 */ const set = (fn?: () => void, intervalTime?: number, isInit = false) => { const timeItem = timerRef.current if(fn) { timeItem.fn = fn } if(intervalTime) { timeItem.intervalTime = intervalTime timeItem.remainTime = intervalTime } if(isInit) return stopTime() timeItem.remainTime -= timeItem.end - timeItem.cur timeItem.cur = Date.now() timeItem.end = timeItem.cur timeItem.timeout = setTimeout(() => { timeItem.cur = Date.now() timeItem.end = timeItem.cur timeItem.remainTime = timeItem.intervalTime timeItem.interval = setInterval(() => { timeItem.cur = Date.now() timeItem.end = timeItem.cur timeItem.fn!() }, timeItem.intervalTime) timeItem.fn!() }, timeItem.remainTime) } 暂停计时器清除计时器和记录暂停的时间,用于重新开始计时器时,计算剩余时间; /** 关闭计时器 */ const pause = () => { timerRef.current.end = Date.now() stopTime() return timerRef.current.end - timerRef.current.cur } /** 停止定时器 */ const stopTime = () => { clearTimeout(timerRef.current.timeout!) clearInterval(timerRef.current.interval!) timerRef.current.timeout = null timerRef.current.interval = null } |
CopyRight 2018-2019 实验室设备网 版权所有 |