函数防抖(等一段时间,然后带着一起做)
以送外卖举例
外卖员只送一家餐厅,每次餐厅来新订单,外卖员都会等5分钟,5分钟之内没有新订单,外卖员开始送餐
5分钟之内有新订单,外卖员会从新计时,直到5分钟内没有新订单,外卖员会把这段时间的订单一起送出
实际需求
持续触发不执行函数,不触发一段时间后再执行函数
思路
使用定时器,每次执行函数前看定时器是否存在,存在就清除定时器,不存在就执行函数
防抖函数 代码
function debounce(fn, delay){
let timerId = null //声明定时器默认为空
return function(){
const context = this
if(timerId){window.clearTimeout(timerId)} //如果定时器存在,清除定时器
timerId = setTimeout(()=>{ //定时器不存在,定时器等于在时间间隔后执行函数
fn.apply(context, arguments)
timerId = null //执行完函数取消定时器
}, delay)
}
}
const debounced = debounce(()=>console.log('hi'))
debounced() //undefined
debounced() //hi
函数节流 (一段时间内,执行一次后就不执行第二次,冷却时间)
以玩游戏举例
每次释放技能都有10秒的冷却时间,冷却时间内,不能再次释放技能
实际需求
持续触发并不会执行多次函数,到一定时间后再去执行函数
思路
通过设置一个开关,与setTimeout结合使用,表示是否可以执行函数
节流函数 代码
function throttle(fn, delay){
let canUse = true //设置开关,true表示可以使用函数
return function(){
if(canUse){ //如果可以使用,就调用函数
fn.apply(this, arguments)
canUse = false //函数执行后,把开关改为不可使用
setTimeout(()=>canUse = true, delay) //在延迟时间后改为可以使用
}
}
}
const throttled = throttle(()=>console.log('hi'))
throttled() //hi
throttled() //undefined
总结
防抖和节流使用setTimeout来控制函数执行时机,可以节约性能,不至于多次触发复杂的业务逻辑而造成页面卡顿