JS中的防抖应用一看就会

防抖这里两个词可能对一些初入JavaScript的同学比较陌生,那这篇文章主要是针对这些同学们的,浅谈一下防抖

1.”防抖”是什么

首先,先去解释一下什么叫做防抖, 在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。纯理论是比较抽象的,还是用代码来的实在。
假设: 我有一个标签,并想获得输入时的值,代码是这样的:

<body>
    <input type="text">
    <script>
        let input = document.querySelector("input");
        input.addEventListener('input',function(){
            console.log(this.value);
        })
    </script>
</body>

我们输入一些值之后,得出的效果是这样的:

我们只是输入了 “前端”两个字,控制台中就打印了很多次,事件就执行了很多次。假设我们每一次输入都是和后台进行一次数据交互的话,那执行这么多次事件就会太影响性能了。
那么我们考虑的就是怎样减少与后台数据库请求的次数,那么防抖就应用而生了。
也就是说 用户触发时间过于频繁,只要最后一次请求的操作就叫做防抖

2.怎么做

用户虽然触发了多次,但是我们想要的只是用户操作的最后一次,那么应该怎样去实现呢?
其实可以把问题简单化,我们只要隔一个固定的事件去获取一次用户输入的值,那么事件触发的次数就会减少,这个就是防抖的实现
现在用代码去实现:

<body>
    <input type="text">
    <script>
        let input = document.querySelector("input");
        let time = null;//time用来控制事件的触发
        input.addEventListener('input',function(){
            //防抖语句
            if(time !== null){
                clearTimeout(time);
            }
            time = setTimeout(() => {
                console.log(this.value);//业务实现语句
                //这里的this指向的是input
            },500)
        })
    </script>
</body>

用 time 来控制事件的触发,然后建立一个延时器,用固定事件500ms来控制事件的触发,输出this.value ,那么之前,需要进行一个判断,判断time是不是有值,如果有值就去清掉time,然后下面的代码又重新赋值给time`。

3.优化:

防抖实现了,但是新的问题又来了,我们定义了一个全局变量time,而且防抖的代码和业务逻辑混到了一起了,那么这个代码就非常不利于维护。那么我们应该怎么解决这个问题呢?这时可以用闭包来封装一个防抖的函数

<body>
    <input type="text">
    <script>
        let input = document.querySelector("input");
        //input事件触发的时候,执行的是debounce返回的function,这个function里面有防抖和真正的业务逻辑
        input.addEventListener('input', debounce(function () {
            /* 
                用debounce函数去约束input这个事件,实际执行的函数是function函数,防抖的延迟是500ms
            */
            console.log(this.value);//业务代码
        }, 500));
        //需要让debounce的返回值是一个函数
        /* 
            fn : 回调函数  传进来的是正真的业务逻辑
            delay : 延时时间
        */
        function debounce(fn, delay) {
            let time = null;//time用来控制事件的触发
            return function () {
                if (time !== null) {
                    clearTimeout(time);
                }
                time = setTimeout(() => {
                    fn.call(this);
                    //利用call(),让this的指针从指向window 转成指向input
                }, delay)
            }
        }
    </script>
</body>

这样,一个真正工程化的防抖就完成了

One thought on “JS中的防抖应用一看就会

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注