1. 介绍
在 JavaScript 中,防抖和节流是一个很重要的概念。主要应用场景就是会频繁触发的事件,比如监听滚动、点赞功能,这时候就要用到防抖和节流。 防抖和节流的核心就是定时器,就是在定时之后,在没触发之前清除定时器,这个定时器方法不会被触发。
1.1 防抖
防抖这个技术点允许我们将多个相似的调用分成一组,或者可以理解为多个相同的事件最后只执行一次。 防抖函数的作用就是控制函数在一定时间内的执行次数。防抖意味着 N 秒内函数只会被执行一次(最后一次),如果 N 秒内再次被触发,则重新计算延迟时间。
1.2 节流
节流函数的实现原理是,将即将被执行的函数用定时器延时一段时间后执行。如果本次延时执行还没有完成,则忽略调用函数的请求。节流函数接受两个参数,第一个是 需要被延时执行的函数,第二个是需要延迟的时间。 节流函数的作用是规定一个单位时间,在这个单位时间内最多只能触发一次函数执行,如果这个单位时间内多次触发函数,只能有一次生效。
2. 具体实现
2.1 防抖
1. 思路
每次触发事件时都取消之前的延时调用方法
2. 代码
<button id="btn">防抖提交</button><!-- 设置表单 -->
<script>
function success(e){
console.log('提交成功')//设置success函数,并且打印结果
}
// 防抖函数
const debounce=(fn,delay)=>{// 1 创建防抖函数debounce
let timer=null // 创建一个标记用来存放定时器的返回值
return (...args)=>{//4 进行解构
clearTimeout(timer)//5 每当用户输入的时候把前一个setTimeout 清除掉
timer = setTimeout(()=>{//3 然后又创建一个新的setTimeout, 这样就能保证输入字符后的 interval 间隔内如果还有字符输入的话,就不会执行fn 函数
fn.apply(this,args)//6 绑定this作用域和接受success参数
},delay)
}
}
const oDebounce=debounce(success,2000)//2 设置间隔2秒执行一次 success被debounce修饰为oDebounce 然后调用
let btn=document.getElementById('btn')
btn.addEventListener('click',oDebounce) // 防抖 click调用oDebounce
</script>
3. 效果
怎么点都没有
一停下来过两秒出现
再次点击
2.2 节流
1. 思路
每次触发事件时都判断当前是否有等待执行的延时函数
2. 代码
<button id="btn">节流提交</button> <!-- 设置表单 -->
<script>
function success(e){
console.log('提交成功')//设置success函数,并且打印结果
}
//节流函数
const throttle =(fn,delay)=>{//1 创建节流函数throttle
let flag=true//5 通过闭包保存一个标记
return (...args)=>{//4
if(!flag) return // 在函数开头判断标记是否为true,不为true则return
flag=false//6 立即设置为false
setTimeout(()=>{//3 将外部传入的函数的执行放在setTimeout中
fn.apply(this,args) // 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。
flag=true //当定时器没有执行的时候标记永远是false,在开头被return掉
},delay)
}
}
const oThrottle=throttle(success,2000)//2 设置间隔2秒执行一次 success被throttle修饰为oThrottle 然后调用
let btn=document.getElementById('btn')
btn.addEventListener('click',oThrottle) // 节流 click调用oThrottle
</script>
3. 效果
疯狂点击还是慢悠悠地间隔两秒执行
3. 小结
函数防抖和函数节流是在时间轴上控制函数的执行次数。防抖可以类比为电梯不断上乘客,节流可以看做幻灯片限制频率播放电影。 我只是一个前端小白,正在死磕js手写36道题目,欢迎交流讨论。
可参考资料: