再谈防抖debounce函数

参考文章

浅谈JS函数防抖及应用场景

1、场景演示

  

  疯狂点击按钮

  

  正常情况下,点击提交按钮,应该发送接口请求 ,如果用户网络不够畅通,接口请求需要1s完成,期间你提交了多次.... ....,此时在后台也就默认接受了很多次的请求,这种方式及其浪费服务器资源,所以需要在前端做个防抖和节流。本节介绍下防抖函数

  需求:1s内点击了10次,则以最后一次点击为准... 

  1、编写防抖函数,然后调用,这里之所以这么快调用,是为了看到效果。最后click点击事件应该调用的是经过防抖函数优化过的success,我们将其绑定到变量oDebounce上

    

  2、开始传入参数:修饰的函数fn和时间间隔delay

    

  3、编写定时器(delay时间后触发fn函数)

    

    测试如下,此时刷新页面时自动调用了该函数

    

    因为改写发存在自动执行

    

    接着点击按钮,发现并没有触发函数

    

    原因:没有返回值,一个方法里嵌套了另一个方法

    

    所以这里应该返回一个方法

    

    此时测试如下,点击每隔1s后才会触发函数

    

    但此时仍然存在问题,即快速点击时,只有第一次点击才会延迟执行,后面都无效... ...

  4、接下来清除定时器即可

    

    此时便可以实现基本结构的防抖函数。

  5、完善1:设置this指向

    为了完善代码,接着优化如下。有时在函数里会用到this,如下

    

    为了防止this指向被修改,我们需要在封装的代码里设置fn的this作用域,防止fn函数的作用域里的this被修改

    

  6、完善2:fn函数有参数的情况

    还要考虑一种情况,即fn存在参数... ...

    

    首先在调用时接受arguments参数,然后在apply里传入即可

    

完整代码如下:

<body>
    <button>提交</button>
    <script>
        var btn = document.querySelector('button')
        function successFn() {
            console.log(666)
        }
        let debounce = (fn, wait) => {
            let timer = null;
            return (...arguments) => {
                clearTimeout(timer)
                timer = setTimeout(() => { 
                    fn.apply(this, arguments)
                }, wait)
            }
        }
        btn.addEventListener('click', debounce(successFn, 1000), false)
    </script>
</body>

  

 

.

原文地址:https://www.cnblogs.com/fightjianxian/p/12743903.html