JavaScript

75 阅读2分钟

防抖节流

1、防抖

概念

触发高频事件后的n秒内只会执行一次,将多次事件触发转化为一次事件触发; 简单通俗来说:就是领导多次叫你干活,你等到领导最后一次叫你之后的n秒后才开始工作

使用场景

  1. 调整窗口的大小的时候,resize事件过多,此时就可以用防抖优化,等待用户调整完毕之后再执行相应的回调函数

  2. 搜索框联想词,等待用户输入完了之后才触发回调

cont debounce = (fn,wait=0) => {
let timer = null 
return function (...args) { //...args 此处是rest类型
clearTimeout(timer)
setTimeout(() => fn.apply(this,...args),wait)

}
}

2、节流

概念

立即执行或者是延迟执行,但是在一段事件内只是执行一次事件

使用场景

  1. 游戏技能,比如王者荣耀的回城操作
  2. 轮播图
  3. scroll事件

两种节流函数

  1. 时间戳版本:第一次执行但是最后一次不执行
const throttle = (fn,wait = 0) => { 
let oldTime = 0 //老时间,确保第一次能够执行
return funtion (...args) {
let newTime = Date.now()//获取现在的时间,一致在更新
if(newTime - oldTime >0 ) {
fn.allpy(this,...args) {
oldTime = Date.now()//记录下当前的时间作为下一次计时的起点
}
}
}

2、定时器版本,第一次不执行,最后一次执行


const throttle = (fn,wait = 0) {
let timer = null 
return function (...args) {
if(!timer) {
timer = setTimeout (() => {
fn.apply(this,...args)
timer = null//令定时器为空 以便于下次在进行触发
},wait)
}
}
}

3、最终结合版本,第一次执行最后一次也执行 (简单来说就是结合了定时器和时间戳一起用)

const throttle4= (fn,wait) => {
  let oldTIme = 0
  let timeout = null
  return function(...args) {
    let newTime  = Date.now()
    if(newTime - oldTIme > wait) {
      if(timeout) {
        clearTimeout(timeout)
        timeout = null
      }
      fn.apply(this,...args)
      oldTime = Date.now()
    }else if(!timeout) {
      timeout = setTimeout(()=>{
        fn.apply(this,...args)
      },oldTIme + wait - newTime)
      timeout = null
    }
  }
}