先看看什么是防抖和节流:
参考 : https://www.jianshu.com/p/f9f6b637fd6c
防抖:(debounce)
英 [dɪ'baʊns] 美 [dɪ'baʊns]
函数防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
理解:
假设,你监听的是scroll 事件 , 你一直滚动的时候 , 不触发回调函数
当你滚动结束 , 就是最后一次scroll 事件之后 ,
执行回调,里面的参数是最后一次scroll 事件触发的, 事件也是最后一次回调的事件 .....
节流:
限制一个函数在一定时间内只能执行一次。
理解:
有限制的数据流 ,
要限制数据流 , 比方说 我规定 一般秒钟 ,只能发送一条请求
类似的使用场景 , 例如有个用户 傻逼 一直去触发下拉加载 .. 我如果没有取消请求的方法, 但是 我也不能让丫 一直请求是不 ...
使用场景总结:
防抖: (连续事件,只执行一次)
- 搜索框 ,用户最后一次输入完 ,就发送请求 ...
- 手机号,邮箱等的输入校验 (也可以触发失焦检验)
- resize 计算窗口大小 ,防止页面重复渲染 ....
节流: (单位之时间内只可以触发一次):
- 滚动加载 , 就是对于滚动到页面底部的监听
- 谷歌搜索框,搜索联想功能 (java es)
- 高频点击,防止表单反复提交 (这个是不是 需要后端做控制啊)
了解实现原理:
防抖:
const _.debounce = (func, wait) => { let timer; return () => { clearTimeout(timer); timer = setTimeout(func, wait); }; };
就是一个闭包 ,配合延时器使用
执行流程:
第一次触发事件的时候 , 触发延时器,不立即执行 ,比方说 ,需要延时 5s执行
第二次触发事件的时候 , 假设在五秒以内 , 就清空之前的定时器, 重新开始下一个 5s ..
以此类推
直到5s内, 没有再次触发 事件, 最后一次的延时器 就可以真正的走完了
节流 :
节流有两种实现的方式 延时器版本 setTimeout 版本 , 和 时间戳版本
随便找一个,理解一下吧 :
const _.throttle = (func, wait) => { let timer; return () => { if (timer) { return; } timer = setTimeout(() => { func(); timer = null; }, wait); }; };
执行流程:
大致的意思,就是给你一个标识, 告诉你 这个回调函数能不能执行,能执行 ,就走
不能执行,就不让过
就和过安检似的
但是,一旦不让你过去 ,你就不在队列里边了
直接 , 换下一个受害者
实践
忘了从哪里抄来的了 , 结合java ES使用
function throttle(callback) { var starttime = Date.now(); var currenttime = null; var timespace = 1000; var timeout = null; return function (self, args) { // 用context和event保存调用事件的this和事件对象 //var context = this; // var event = arguments[0] currenttime = Date.now(); if (currenttime - starttime > timespace) { clearTimeout(timeout); starttime = Date.now(); timeout = null; // 使callback绑定事件调用对象,和事件对象 //callback.call(context, event ,self, args) callback && callback(self, args) } else { // 判断有无定时器 if (!timeout) { // 没有定时器的话,打开定时器 timeout = setTimeout(function () { // 使callback绑定事件调用对象,和事件对象 //callback.call(context, event, self, args); callback && callback(self, args); // 调用完成后将timeout清空 timeout = null; }, 1000) } } } }
建议:
百度的搜索, 是可以取消请求的
jquery 貌似也有类似的方法
promise 请求不可以取消
不如使用RsJS 的方案,更优
结合lodash 进行使用:
千万不要重复的造轮子 ...
自己查API