节流防抖
防抖
顾名思义就是防止手抖
防抖会给我们容错时间,如果在这个容错时间内再次触发事件,则会直接撤销上一次操作的定时,再给最新的这次事件定时
核心思想是:当事件被触发的时候,设定一个容错时间延迟执行动作(计时器),若这期间再次被触发,则重新设定周期(清除上一次计时器,重新定时),直到容错时间结束,才触发事件执行动作
可以想象成将一个弹簧按下,继续加压,继续按下,只会在最后放手的时候反弹,即我们希望函数只会调用一次,即使在这之前反复调用它,最终也只会调用一次而已
function debounce(func, delay){
//定义一个定时器
let timer = null
return function(...args){
//清除上一次的计时器
clearTimeout(timer)
//重新计时
timer = setTimeout(() => {
func.apply(this, args)
}, delay)
}
}
在这里,我们使用了闭包,原因是我们需要在每一次进入函数体的时候都要清除上一次的计时器,所以在这里计时器必须放在返回的函数外部形成闭包,做到计时器共享,也就是下一次执行函数的时候能够访问到上一次赋值的计时器
并且,在执行func函数的时候,我们使用了apply重新绑定了一下this,这是因为每次调用函数的时候必须确保上下文的正确,所以要显式绑定this,同时函数还要传递参数,所以直接使用apply即可
节流
顾名思义就是节省流量
函数在一定时间内只会执行一次,如果在这段时间内再次触发事件了,就会直接无视,直到这段时间结束
核心思想是:在固定一段时间内,只执行一次函数,若这段时间有新事件触发,则选择不执行。当这段时间结束后,又有事件触发,才再次开始一段保护期
可以想象成游戏中的技能冷却,只有时间到了才能重新出发,中间点多少次都没用
function throtte(func, time){
//计时器
let timer = null
return function(...args){
//如果存在计时器则无视,直接返回
if(timer) return
//如果没有计时器则新建一个计时器
timer = setTimeout(() => {
func.apply(this, args)
}, time)
}
}
应用场景
防抖:
- 搜索框联想,用户在不断输入值时,用防抖来节约请求资源
- window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次
节流:
- 鼠标不断点击触发,让单位时间内只触发一次
\