防抖和节流
防抖和节流
节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
防抖: n 秒后再执行该事件,若在 n 秒内被重复触发,则重新计时
目的都是,降低回调执行频率。节省计算资源
防抖
类似于 回城
按B回城,回城中再按B,重新回城
只执行最后一次
先来看个例子:
假设input是一个搜索框,每次输入完都会控制台输出 输入的内容。
结果:
如图,这里仅仅输入了一个 “前” 就触发了这么多次,那如果是每次输入完,进行一次搜索岂不是非常浪费资源
插入防抖
思路:
封装了一个函数debounce,fn -> 执行的函数,delay -> 间隔时间,通过return内部函数形成闭包,使 t 不会被清除。
第一次触发事件 t保存定时器唯一标识 ,开启定时器(开始计时),只有经过delay指定时间才会执行定时器里的代码。
除了第一次触发之后每次触发都会清除上一次的定时器
如果下一次触发与上一次触发间隔时间小于delay,就代表上一次的setTimeout还没有执行,就被清除了。
然后再开启一个新的定时器开始计时,经过delay指定时间 就执行定时器里的代码。
注意:定时器要用箭头函数拿到this,然后用指定this调用fn,这样fn的this才是指向inp的
结果:
节流
类似于 技能CD
按Q释放Q技能,然后Q技能进入CD,CD没好不能再次释放Q技能,如果CD好了就可以再次释放
控制执行次数
例子:
给全局对象window绑定一个滚动事件,滚动一次控制台输出'Hello World'
结果:
可以看到仅仅滚动了一点,这个事件就触发了40次,那如果是要滚动一次向服务器发送一次请求的话,那岂不是发送了40次?
插入节流
这里将结果一并放到图中
思路:
与防抖(debounce)同样的两个形参,fn -> 执行的函数,delay -> 间隔时间,通过return内部函数形成闭包,使 flag 不会被清除
第一次调用:flag默认值为true,判断flag ,开启定时器(开始计时),然后让 flag = false。
每次调用都会判断 flag 并让 flag = false
下一次触发如果与上次一触发间隔小于delay(指定时间),那就代表上一次的setTimeout还没有执行,只有setTimeout执行了 flag 才为 true。
这时 flag 依然为 false,所以不会开启定时器。
连续触发情况下,必须等待上一个定时器执行后 flag为true,下一次触发才会开启定时器
注意:这里的定时器也要用箭头函数拿到this。
结果:
如图,明显减少了触发的次数
总结
防抖:用户触发事件过于频繁,只要最后一次触发生效
节流:用户触发事件过于频繁,控制事件执行次数
由于上面都是图片,这里将两个函数放到下面方便自取:
// 防抖
function debounce(fn, delay){
let t = null
return function(){
if(t !== null){
clearTimeout(t)
}
t = setTimeout(() => {
fn.call(this)
},delay)
}
}
// 节流
function throttle(fn, delay){
let flag = true
return function(){
if(flag){
setTimeout(() => {
fn.call(this)
},delay)
}
flag = false
}
}
本文来自博客园,作者:ycccc丶,转载请注明原文链接:https://www.cnblogs.com/imycc/p/16512209.html