在实际开发中有许多高频触发的业务,例如:抽奖、动画等,这时我们需要用到防抖或者节流操作来优化业务。
防抖
防抖:触发高频事件后 n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触发,则重新计算时间。
思路:每次触发事件时都取消之前的延时调用方法。
举个例子:
有一个炸弹按一次开始键 就倒计时15分钟触发爆炸,再15分钟以内再次开始按键,
从新计时15分钟后触发。
代码实现:我们先需要封装一个函数作为工具函数,有两个参数第一个参数为我们想要执行的业务函数,第二个参数为我们设置的延迟时间;执行工具函数要返回一个闭包操作业务函数,将业务代码放在定时器内,再次触发函数时,取消定时器,再从新设置定时器。注意工具函数的返回值必须是一个函数,因为事件的属性绑定等于的是一个函数。
具体看代码:
document.onclick=fangdou(function(){
console.log("1秒打一次");
},1000)
function fangdou(ywfun,delay){
//定义一个变量接收定时器
var timer = null
//返回一个闭包,操作防抖函数传入的数据
return function(){
//清除上次的定时器
clearTimeout(timer)
//延时执行业务
timer=setTimeout(function(){
ywfun()
},delay)
}
}
节流
节流:高频事件触发,但在 n 秒内只执行一次,所以节流会稀释函数的执行频率。
思想:每次触发事件时都判断当前是否有等待执行的延时函数。
举个例子: 食堂打饭时突然来了很多人,但是要前面一个人打完后,后面一个人才能打饭。
代码实现:我们也是先需要封装一个函数作为工具函数,有两个参数第一个参数为我们想要执行的业务函数,第二个参数为我们设置的延迟时间;执行工具函数要返回一个闭包来操作业务函数,将业务代码放在定时器内,再次触发函数时,有一个条件判定语句,只有符合时再触发定时器。注意工具函数的返回值必须是一个函数,因为事件的属性绑定等于的是一个函数。
具体看代码:
document.onmousemove=jieliu(function(){
console.log("0.5秒打印一次");
},500)
function jieliu(ywfun,delay){
//设置一个变量接收定时器
var timer=null
//返回闭包
return function(){
//设置判断条件timer==null才执行,
//一但执行,timer的值就变成了定时器,只有设置的延迟时间过了执行了timer=null以后才会再次执行
if (timer==null) {
timer = setTimeout(function(){
ywfun()
timer=null
},delay)
}
}
}
这里的代码只是简单的实现,还可以有很多的优化。
总结:
防抖和节流本质是不一样的。防抖是将多次执行变为最后一次执行,节流是将多次执行变成每隔一段事件执行。
防抖和节流降低回调执行频率,节省计算资源。其思想容易理解,难在的是代码的编写,大家多加练习。