炒鸡简单的理解防抖和节流与其使用场景

408 阅读3分钟

前言

函数防抖和函数节流是面试题的常客了,所以我们还没有了解的兄弟萌赶紧看起来吧!

u=1059470945,3696048767&fm=253&fmt=auto&app=120&f=JPEG.webp

概念和例子

函数防抖(debouce)

事件在触发后过n秒再执行回调函数,如果这个事件在n秒内再次被触发,则会重新计时。 这是什么意思呢,就是字面意思,就好比你玩CF里面的加特林,你必须得按住鼠标级几秒钟之后才能开枪,如果你猛点鼠标,这枪管就一直得重新蓄力。函数防抖就类似于此,就是为了防止多次的连续点击。

  1. 我们举一个普通例子
      let btn = document.getElementById('btn')  //获取到页面的一个dom按钮
       btn.addEventListener('click',a)          //给它添加监听事件
       function a(){
       console.log('提交成功');}

运行结果:

123.gif 我们可以看到,我们点击多少次,就会打印多少次。这在我们的数据请求过程中是非常不友好的。所以 我们可以用函数防抖也解决这一问题。

2.添加函数防抖

  let btn = document.getElementById('btn')
  btn.addEventListener('click',debance(a,1000))
  function a(){
  console.log('提交成功');
  }
  
  function debance(fn,delay){  //防抖函数
    let timer = null           //保存上一次的定时器
    return function(){
    clearTimeout(timer)      //清除定时器
    timer = setTimeout(()=>{ 
    fn.apply(this)       //因为这里是箭头函数,this指向的是return 的匿名函数,使fn的this指向btn                     
    },delay)
  }
}

我们看加了防抖之后的运行结果:

456.gif 我们可以看到在我们一直点击按钮的时候并不会显示输出,只有当停下来过了一秒后才显示输出。

  • 防抖的 实现核心就是利用闭包来保存住上一次的定时器,当在规定单位时间内再次点击时,清除上一次的事件,并重新开始一个新的定时器。

函数节流(throttle)

节流是在一个规定时间内只触发一次函数,如果在这个规定时间内触发多次函数,也只会生效一次 这个就比较好理解了,这就相当于你在打连狙,你不停的点击鼠标开枪,但是枪还是只会有规律的每隔一段时间开一枪,这就是节流的意义了,节约流量嘛。

  1. 添加节流函数
   let btn = document.getElementById('btn')
   btn.addEventListener('click',throttle(a,3000))
    function a(){
     console.log('提交成功');
}

  function throttle(fn,delay =1000){
     let prex = 0
      return function(){
      let now =  Date.now()         //定义一个时间戳
      if(now - prex >=delay){       //如果这一次的点击时间减去上一次的点击
          fn.apply(this)            //因为fn的this指向window,所以要用apply修改this指向btn
          prex = now                //并把这一次的时间赋值给prex
     }
   }
}

我们看输出结果:

789.gif

我们可以看到,当我们把规定时间内设置成三秒后,我们不断的点击按钮,按钮也只会在第一次点击输出后每隔三秒输出一次。

  • 节流的实现核心也是利用闭包来保存上一次点击的时间,如果下一次的点击时间与上一次的点击时间小于规定时间,则不会触发输出函数

总结

  • 函数防抖和节流都是为了防止在一定时间内频繁点击。

  • 防抖是在一定时间内只执行一次,节流是间隔单位时间持续执行。

应用场景

防抖和节流的实现原理不同,这就导致了它们的运用场景也不相同

  • debouce
    • 用户在搜索时,不断输入值或者发起接口请求时,用防抖也节约请求资源
  • throttle
    • 鼠标不断点击触发,mousedown(单位时间内只触发一次)