前端项目防抖函数的使用

54 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第20天

防抖函数

今天在学习的项目中,为了解决容器在服务器图片还未完全响应时就固定高度,导致图片加载完成后溢出的问题,进行了如下方案的尝试:

方案一

进行延迟后刷新

setTimeout(refresh, 500)

优点:简洁易懂

缺点:时间被写死,对于网速好的用户会卡顿至体验不佳,对于网速慢的用户可能时间不够,仍然会出现溢出问题

方案二

监听图片加载时间,等图片加载完毕后再进行刷新

this.$on('itemImageLoad', () => {
    this.element.refresh()//refresh是element中已定义的刷新方法,element就是需要刷新的组件
})

优点:这种方案可以很及时地进行刷新响应

缺点:每次监听都进行刷新操作占用了一定资源,如果有数百张图片,就进行数百次刷新,这显然是不太好的

方案三

为解决方案二的多次刷新,这里就用到了防抖函数,核心思想就是,将多次触发短间隔刷新的事件阻拦下来,再定时一次性触发,这样缩短了刷新次数,提高了性能

debounce(func, delay) {
    let timer = null
    return function(...args){
        if(timer) clearTimeout(timer)
        timer = setTimeout(()=>{
            func.apply(this, args)
        }, delay)
    }
}

这样我们监听后对debounce方法进行调用,func参数处传入要调用的方法,delay表示要延迟的毫秒数,apply这里主要不是为了改变this指向,主要做传参数用,apply中传入的args为数组。

每次监听到图片加载完成事件,调用debounce方法,先定义timer接收setTimeout的返回值,随后rerturn一个函数实现闭包,取消上一次的定时器,定义新的定时器,如果在定时器到时限前再次有监听事件触发方法,则会继续取消当此定时器,开启新的一轮计时,直到delay时间内再无新的图片加载事件触发,才会进行刷新。