手撕-防抖函数

1.为什么需要防抖

我们这里通过一个场景说明为什么我们需要进行防抖,下面是一个动画,我通过快速地点击按钮,打印出对应的文字。这看着并没有什么问题,对吧!

动画.gif

但是想象一下如果上面的按钮,可以请求后端接口呢,这个时候时候如果快速地点击按钮,就会造成服务器的请求数增大,从而可能对服务器产生一定的影响。

2. 怎么解决

抖动,我们有时候由于一些反应,会导致我们的手快速抖动,这个时候,为了不让我们手的抖动影响了正常的工作,我们通常会使用另外一只手按着它,而这种借助某种方式,控制抖动,就是我们要思考应该如何解决的问题

解决思路:借助某种方式,我们可以想到采用定时器的方式来控制,settimeout()可以让对应的回调函数延迟执行。这个我们可以借助,大致的思路为:

  1. 正常情况,我们总是让我们触发的事件推迟几秒再去执行
  2. 如果在推迟的这个时间内,非常着急还是想触发这个事件,那么对不起,你触发不了,因为你每次一触发事件,我们就把定时器清空,然后再次触发的话,还是这么个过程。
  3. 所以最后实际执行的事件是最后一次触发的事件

3.代码实现

因为timer我们始终要用到,所以通过闭包来让定时器一直存在于内存中。

function debence(fn, wait) {
    let timer = null;
    // 因为timer我们是要使用多次的
    return function() {
            let context=this,
            args=arguments;
            if(timer){
                    clearTimeout(timer);
                    timer=null;
            }
            timer=setTimeout(()=>{
                    fn.call(context,...args);
            },wait)
    }
}

let btn=document.getElementById("btn");
btn.addEventListener('click',debence(()=>{console.log("哈哈哈")},1000))

4.防抖效果显示

动画1.gif