js中的函数防抖

100 阅读2分钟

「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战

函数防抖

何为函数防抖,函数防抖是一种优化性能的操作,函数防抖常用于输入框、检测窗口变化等情况下。

举个例子:

根据输入框中的内容来请求接口,如果输入框没有做函数防抖,那你每次输入都会触发请求接口的函数,那么你输入10个字母就会触发10次请求,这显示是非常消耗性能的,也不合理,我们完全可以在它输入多个字母后再去请求接口,这就要用到防抖来实现了,防抖就是我们设定个时间段(这里假设是300ms),那么当你输入一个字母后如果过了300ms还没有其它输入,那么就请求接口,如果在300ms内又再次输入了,那么就从0开始再等300ms,直到300ms内没再输入才去请求接口

代码如下:

    //在vue中的使用方法
    methods:{
        debounce: (function () {
            let timer = null
            return function (value) {//参数在这里接收,如果写在外层函数会接收不到(自运行函数的写法)
            clearTimeout(time)
            //下面的function函数就是你要做的具体操作
            timer = setTimeout(function () { console.log(value) 
        }, 300)
      }
    })(),//自运行函数
    }
     //使用的时候如下即可使用
     this.debounce(value)

由于上面的方法用了闭包,所以debounce函数我们要写成自运行函数,由于使用了自运行函数,所以参数要直接写在闭包上来接收。

上面是直接写在methods中的使用方法,比较简陋,没有判断timer是否存在就删除了定时器,并且没有设置是否立即执行,下面的写法比较完善,我们也可以写在js文件中引入时使用

    //debounce.js
    export function debounce (func, delay = 300, immediate = false) {
        let timer = null
        return function () {
            if (timer) {
                clearTimeout(timer)
            }
            if (!timer && immediate) {
                func.apply(this, arguments)
            }
            timer = setTimeout(() => {
                console.log(this, arguments)
                func.apply(this, arguments)
            }, delay)
        }
    }
    //使用方法
    import { debounce } from '@/utils/debounce.js'
   
    this.idSearch(value)
    
     idSearch: debounce(function (value) {
         //这里就是你要进行的一些操作
        getHdCodeByOrgId(value).then((res) => {
           if (res.data.hdCode) {
             this.hdCode = res.data.hdCode
             this.form.setFieldsValue({ hdCode: this.hdCode })
             this.hdCodeChange = true
           } else {
             this.form.setFieldsValue({ hdCode: '' })
             this.hdCodeChange = false
           }
         }).catch((err) => {
           this.$message.error(err.data.message)
         })
       }, 300),

除了上述两种写法外,还有一种可以直接写在vue中的写法,另外定义函数,传入函数在调用时改变this指向

    data(){
        return {
            inputData: () => {}
        }
    }
    mounted(){
        this.inputData=this.debounce()
    }
    //调用的时候直接写
    this.inputData()
    
    methods:{
        debounce (value) {
            let timer = null
            return function () {
                if (timer) {
                    clearTimeout(timer)
                }
                timer = setTimeout(() => {
                //do something
                 console.log(11)
                }, 300)
                }
            },
        }