再谈防抖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>
.