应用场景:input的onchange/oninput,鼠标mousein,mouseout,鼠标的scroll等高频事件,触发函数fn,此时我们用节流throttle方法和debounce方法对函数fn做一层处理:
1.节流 throttle:
事件在n 秒内,只执行一次:
代码示例:
let throttl=(fn,n)=>{
let timer;
return function(){
let self = this,args = arguments;
if(timer) return
timer = setTimeout(function(){
fn.apply(self,args)
timer = null;
},n)
}
}
代码解释:
事件第一次触发,执行throttl函数,赋值timer延时器,并在n 毫秒之后执行,
当第二次触发执行throttl时间间隔距离第一次次事件大于n毫秒,此时第一次的延时fn已执行,第二次的fn照常n毫秒后执行
如果第二次触发执行throttl时间间隔距离第一次次事件小于n毫秒,此时timer在function函数内,已经声明,直接return出去,不会执行延时器,
注意,延时器执行完成之后,timer要重新赋值null。
2.防抖 debounce:
在事件被触发n秒后再执行回调,如果在这n秒内又被触发不会执行fn,则重新计时。
一个比较生动的例子:防抖函数就就像,法师发技能的时候要读条,技能读条没完再按技能就会重新读条。
代码示例:
let debounce = (fn,n)=>{
let timer;
return function(){
let self = this, args = arguments;
if(timer) clearTimeout(timer);
timer = setTimeout(function(){
fn.apply(self,args)
},n)
}
}
代码解释:
事件第一次触发,执行debounce 函数,赋值timer延时器,并在n 毫秒之后执行,
当第二次触发执行debounce 时间间隔距离第一次次事件大于n毫秒,此时第一次的延时fn已执行,第二次的fn照常n毫秒后执行
如果第二次触发执行debounce 时间间隔距离第一次次事件小于n毫秒,此时timer在function函数内,已经声明,此时清除第一次声明的timer,并且再次声明一个新的timer,并在n毫秒之后再执行,
总结:throttle节流,一定时间里只执行一次,多次触发也只执行一次,注意代码里面的return;
debounce防抖,事件被触发n秒后再执行回调,如果在这n秒内又被触发不会执行fn,则重新计时。(法师发技能的时候要读条,技能读条没完再按技能就会重新读条,法师的技能只释放了一次),两者区别的关键代码(个人理解),throttle是直接return出去,debounce是重新赋值timer后再执行。
本文只是节流和防抖的一种入门的写法,有兴趣的同学可以移步掘金或者思否更深入了解