浅析函数防抖和节流的实现

268 阅读2分钟

mmexport1618146614602.jpg

1. 介绍

在 JavaScript 中,防抖和节流是一个很重要的概念。主要应用场景就是会频繁触发的事件,比如监听滚动、点赞功能,这时候就要用到防抖和节流。 防抖和节流的核心就是定时器,就是在定时之后,在没触发之前清除定时器,这个定时器方法不会被触发。

1.1 防抖

防抖这个技术点允许我们将多个相似的调用分成一组,或者可以理解为多个相同的事件最后只执行一次。 防抖函数的作用就是控制函数在一定时间内的执行次数。防抖意味着 N 秒内函数只会被执行一次(最后一次),如果 N 秒内再次被触发,则重新计算延迟时间。

1.2 节流

节流函数的实现原理是,将即将被执行的函数用定时器延时一段时间后执行。如果本次延时执行还没有完成,则忽略调用函数的请求。节流函数接受两个参数,第一个是 需要被延时执行的函数,第二个是需要延迟的时间。 节流函数的作用是规定一个单位时间,在这个单位时间内最多只能触发一次函数执行,如果这个单位时间内多次触发函数,只能有一次生效。

2. 具体实现

2.1 防抖

1. 思路

每次触发事件时都取消之前的延时调用方法

2. 代码

<button id="btn">防抖提交</button><!-- 设置表单 -->
    <script>
        function success(e){
            console.log('提交成功')//设置success函数,并且打印结果
        }
        // 防抖函数
        const debounce=(fn,delay)=>{// 1 创建防抖函数debounce
            let timer=null  // 创建一个标记用来存放定时器的返回值
            return (...args)=>{//4  进行解构
            clearTimeout(timer)//5  每当用户输入的时候把前一个setTimeout 清除掉
            timer = setTimeout(()=>{//3 然后又创建一个新的setTimeout, 这样就能保证输入字符后的 interval 间隔内如果还有字符输入的话,就不会执行fn 函数
                    fn.apply(this,args)//6 绑定this作用域和接受success参数
                },delay)
            }
        }
        const oDebounce=debounce(success,2000)//2 设置间隔2秒执行一次  success被debounce修饰为oDebounce 然后调用
        let btn=document.getElementById('btn')
        btn.addEventListener('click',oDebounce) // 防抖 click调用oDebounce
    </script>

3. 效果

怎么点都没有 image.png 一停下来过两秒出现 image.png 再次点击 image.png

2.2 节流

1. 思路

每次触发事件时都判断当前是否有等待执行的延时函数

2. 代码

<button id="btn">节流提交</button> <!-- 设置表单 -->
    <script>
        function success(e){
            console.log('提交成功')//设置success函数,并且打印结果
        }
        //节流函数
        const throttle =(fn,delay)=>{//1 创建节流函数throttle
            let flag=true//5 通过闭包保存一个标记
            return (...args)=>{//4
                if(!flag) return  // 在函数开头判断标记是否为true,不为true则return
                flag=false//6  立即设置为false
            setTimeout(()=>{//3 将外部传入的函数的执行放在setTimeout中
                fn.apply(this,args) // 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。
                    flag=true               //当定时器没有执行的时候标记永远是false,在开头被return掉
                },delay)
            }
        }
        const oThrottle=throttle(success,2000)//2 设置间隔2秒执行一次  success被throttle修饰为oThrottle 然后调用
        let btn=document.getElementById('btn')
        btn.addEventListener('click',oThrottle) // 节流 click调用oThrottle
    </script>

3. 效果

疯狂点击还是慢悠悠地间隔两秒执行 image.png

image.png

image.png

3. 小结

函数防抖和函数节流是在时间轴上控制函数的执行次数。防抖可以类比为电梯不断上乘客,节流可以看做幻灯片限制频率播放电影。 我只是一个前端小白,正在死磕js手写36道题目,欢迎交流讨论。

可参考资料:

juejin.cn/post/684490…

juejin.cn/post/694602…