阅读 252

防抖debounce && 防抖函数的作用

前言

最近在跟进学习一个vue项目,其中在学习过程中遇到防抖,我想对这个防抖函数进行复盘,总结一下。

背景

项目里我监听了图片的加载,通过console进行打印,图片有30张,所以会打印30次。其实我只想监听到第30张加载完成,然后进行回调函数。所以为了减少打印的次数,减少频繁的更新,通过防抖函数进行优化

正文

我们先来看看什么是防抖?为什么要防抖?有啥作用?具体咋写?

什么是防抖?

在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。

个人理解就是游戏人物放大招需要进行一定时间的充能(撇大招),如果这个过程被打断了,就需要重新充能
复制代码

为什么要防抖?有啥作用?

优化项目的性能,让项目运行的更快更好。
可以减少频繁的更新、函数的重复调用、多次的网络请求、订单的多次提交等情况

还有一个重要作用就是面试可能会问,我们必须知道。
复制代码

具体咋写?

第一个参数是我们要执行的函数
第二个就是时间
debounce(func,delay) {  
  let timer=null
  return function (...args) {  
    if(timer) clearInterval(timer) //先判断是否有上一次留下的定时器,有就删除,防止影响当前要执行的定时器
    timer=setTimeout(()=>{  //...args,...代表我们可以传多个参数
      func.apply(this,args)
    },delay)
  }
  //形成了闭包,引用了外部的timer,timer不会被销毁
}


这种功能性的函数,其实会用到很多地方,我们可以额外将其封装成一个js文件,
通过export function将其导出,再到具体使用文件里导入然后调用函数
复制代码

咋用呢?

这里结合项目来说

没有使用防抖debounce函数的情况

this.$bus.$on('itemImgLoad', () => {
        this.$refs.scroll.refresh()   //可以理解为刷新功能,加载完一张就会刷新一次。
        //但其实不需要一直刷新,只要有不低于一次的刷新就行
      })
复制代码
refresh() {
        this.srcoll && this.scroll.refresh()
        console.log('--')   //打印了30次
      }
复制代码

这是通过一个事件总线完成了一个非父子组件之间的通信。我们对图片加载进行监听,图片有30张,所以打印了30次

使用防抖debounce函数的情况

//const refresh = this.debounce(this.$refs.scroll.refresh)
const refresh = this.debounce(this.$refs.scroll.refresh, 50)
      this.$bus.$on('itemImgLoad', () => {
        refresh() 
      })
复制代码
refresh() {
        this.srcoll && this.scroll.refresh()
        console.log('--')  
      }
复制代码

结果如下,打印的次数减少了,次数的多少取决于从服务器加载数据的快慢

微信截图_20210416111442.png

const refresh = this.debounce(this.$refs.scroll.refresh)

这里又涉及了一个小知识点,如果我不给时间然后进行打印,打印的次数也会比30次小很多。
因为当我们选择使用setTimeout,它是异步操作,不管写不写,他都会比其他直接运行的程序代码慢,
后面我也会写一篇关于setTimeout的总结
复制代码

总结

防抖函数是指在某一段时间内只执行一次

其实还有一个函数节流throttle,下一次也写一篇。在这里在这里 掘金:节流throttle

结合应用场景

1.搜索框联想,用户在输入值的时候,用函数防抖来减少请求数据的次数。

2.给按钮加函数防抖防止表单多次提交。

3.为了进行某一个函数调用,监听图片元素或其他元素的加载,函数防抖来减少函数调用的次数

4.。。。。。。还有好多,只不过还没有遇到

拓展

SegmentFault:函数节流与函数防抖

掘金:函数节流与函数防抖

文章分类
前端
文章标签