一.什么是防抖和节流
函数防抖(debounce)
当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新延时。
前端开发过程中的resize,scroll,mousemove,mousehover等,会被频繁触发,不做限制的话,有可能一秒之内执行几十次、几百次,如果这些函数内部执行了其他函数,尤其是执行了操作DOM的函数,那不仅会造成计算机资源的浪费,还会降低程序运行速度,甚至造成浏览器卡死、崩溃。
函数节流(throttle)
二.防抖和节流的简单实现
// 防抖函数
let debounce = (fn, delay) => {
let timer = null;
return function (...args) {
timer && clearTimeout(timer)
timer = setTimeout(()=>{
fn(...args)
}, delay)
}
}
函数防抖存在的问题
如果,一直触发事件,且每次触发事件的间隔小于delay,那就无法触发。
// 节流函数
let throttle = (fn,delay)=>{
let flag = true;
return function(...args){
if(!flag) return;
flag=false
setTimeout(()=>{
fn(...args);
flag=true
},delay)
}
}
三.利用时间戳完善节流函数
我们都知道,有时候setTimeout会存在一定的误差,因为宏任务有时会被阻塞,这时候需要利用时间戳更好的优化我们的节流函数
const throttle = (func, wait = 50) => {
let lastTime = 0 // 上⼀一次执⾏行行该函数的时间
return function(...args){
let now = +new Date() // 当前时间
if(now - lastTime > wait){
// 将当前时间和上一次执行函数时间对比
// 如果差值大于设置的等待时间就执行函数
lastTime = now
func.apply(this,args)
}
}
}
setInterval(
throttle(() => {
console.log(1)
}, 500),
1
)