react防抖节流钩子?

2023-4-11 948 4/11

重复造轮子的一天,写一下简单的防抖节流的钩子,返回的是一个函数对象

一般都是直接使用lodash中的防抖节流的函数,那么自己去造下简单的防抖节流的钩子,也需要利用闭包去存储下定时器Id和时间戳

如果使用常规的写法去制造防抖节流的钩子,然后在组件中引入使用时会发现当你页面状态刷新,那么防抖节流会出现奇怪的bug,是由于没有对事件进行缓存,每次状态刷新后都是重新开始的计算,防抖与节流便会失效,且触发的事件在每一次都是满足条件的。那么对于防抖而言每次到达时间后都会被投入到宏任务队列中,预算便考虑使用useCallback在钩子函数中做一下缓存,就可以解决该问题

 

简易实现:

防抖:我这里主要是使用定时器去实现的,点击后通过定时器,如果超出设定的时间,那么定时器到时会把对应的事件投入到宏任务队列中去(定时器是宏任务),等待一个执行,如果在规定时间内有被触发,那么会清除上一次的定时器Id,然后在把本次的事件去通过定时器去计时,在投入到对应的队列中去

export const useThrottle = (func: any, time: number, flag = true) => {

let lastTime = new Date().valueOf()//初始触发时间

let fun=useMemo(()=> (...parm: any)=> {

const nowTime = new Date().valueOf()//获得当前的时间戳

if (flag) {//区分首次

func(...parm); flag = !flag

return

}

if (nowTime - lastTime >= time) {

func(...parm);

lastTime = nowTime;

}

else {

return;

}

},[])//返回的一个函数对象

return fun

}//节流 (可以优化 在加一个定时器实现尾调用的问题)

 

 

 

节流:我主要是利用的是时间戳去实现的,通过本次触发的时间戳减去上一次的时间戳来判断是否超过了规定的时间,没有超过则不执行该次事件,超过的话则立即执行

export const useThrottle = (func: any, time: number, flag = true) => {

let lastTime = new Date().valueOf()//初始触发时间

let fun=useMemo(()=> (...parm: any)=> {

const nowTime = new Date().valueOf()//获得当前的时间戳

if (flag) {//区分首次

func(...parm); flag = !flag

return

}

if (nowTime - lastTime >= time) {

func(...parm);

lastTime = nowTime;

}

else {

return;

}

},[])//返回的一个函数对象

return fun

}//节流 (可以优化 在加一个定时器实现尾调用的问题)

 

- THE END -
0

非特殊说明,本博所有文章均为博主原创。

共有 0 条评论