一、节流存在意义和使用背景
· 节流在开放中的需求场景其实很常见,下面就举个几个适用节流来优化的常见场景 ·
- 某页面因为网络卡顿或者其他原因导致某个时刻的后台请求不能立马被响应,恰好此时,用户操作触发一次网络请求(例如点击了一下功能按钮),但是因为卡顿等原因,没有及时给用户提供本次请求应有的正向反馈效果。此时用户 可能会出现 高频率的重复操作(例反复点击一个按钮)的操作,那么就会导致页面前端发送相同数量的网络请求至后端,造成不必要的服务器压力和 可能出现的未知错误。
- 实际开放中,第三方UI组件库基本上都会使用,一般库里都会有一个Message 全局消息提示组件。一般使用这个组件都是在某个操作完成之后执行一个消息提示弹窗。那么可能就会出现这种情况:频繁的进行某个能弹出消息弹框的操作,导致同时间内消息弹框在当前页面出现多个叠加,然后逐个消失的情况。
上述类似场景都可以通过节流来控制优化,避免此类类似问题。
二、节流是什么
节流:和字面意思一致,可以理解为,控制某段数据流。
作用:控制事件流量,限制用户在与页面交互时控制事件发生的频率。
实现原理:代码控制单位事件内,某事件发生的次数。(也可以理解为:某个事件在预设的单位时间内只能执行一次)
1.生活小案例
经典游戏-坦克大战 大部分人童年都有玩过。那么遇到"基地"要被打穿或者 战况激烈的时候,想必大家都会疯狂操作游戏手柄,狂按射击按钮。那么细心的朋友肯定发现,当你快速的点击射击按钮的时候,当频率达到一定时,坦克打出的子弹 其间距就会相同,证明,不存在按得越多,子弹打出的频率越高,子弹的打出频率是被限制的,当按键频率和限制频率相同或者,按键频率大于限制频率的时候,就会出现打出子弹间距相同的画面。此处就是一个很好的节流例子。可以很好的体现了,节流是单位时间内限制事件的触发次数。
2.节流实现的案例dome
想要实现节流就必须得定义和控制“节流阀”;所谓“节流阀”:放在代码层面就是一个控制数据流运行的变量。
下面 直接上一段 代码dome ,描述节流的实现:
<body>
<button id="btn">点击</button>
<script>
// 当我狂点鼠标的时候,不能无限制的输出123;约定1s之内,最多只能输出1次123
// 做法:控制定时器,不能重复设置(必须等前一个定时器执行完,才能设置下一个定时器)
// 点击按钮,输出123
// timer 就是节流阀
// timer = null ,表示节流阀打开,此时允许创建定时器
// timer = 数字 ,表示此时有定时器,节流阀关闭,不允许创建定时器
let throttle = null;
document.getElementById('btn').addEventListener('click', function () {
console.log('点击了');
// 判断定时器是否执行完毕了?????
if (throttle) {
// 说明此时有定时器在执行,不允许代码继续执行了(因为继续向后执行的话,有会创建一个定时器)
return;
}
throttle = setTimeout(() => {
console.log(throttle)//数字1 如果定时器代码最后一行timer = null;未执行,就算定时器代码为走完,在没有执行完的情况下,再触发点击事件,timer=1,if(timer){return},return执行,就不会再执行,定时器中代码,
console.log("我是一秒执行一次的,不要快点了哦");
// 当前定时器执行完毕,恢复timer=null
throttle = null;
}, 1000);
})
</script>
</body>
1.变量 throttle 即为当前代码的节流阀, 初始值为 null 。
2.代码执行流程解读:在事件函数中 if(throttle)return;当throttle = null 时,代码向下执行;当throttle = 任何 布尔转换后为 true 的值 时,都会 return,跳出当前代码,不向下执行。
3.逻辑代码中通过 setTimeout 延时器来控制单位时间。
数据流:第一次执行时,throttle = null ,执行下面代码,执行完延时器后,当前throttle 等于 延时器的标识。并且只有在当前事件1s后,throttle 才会又被赋值null ,所以在 这1s内 ,如果多次触发点击事件,这些触发的事件,将会在if(throttle)处,被拦截。直至 throttle 被完成赋值 null 为止(也就是 第一次触发事件的1s之后)。
运行结果如下:
运行结果:
1.前三次点击按钮的间隔时间都大于1秒。所以 “点击了” 和 “我是一秒执行一次的,不要点快了哦” 都是对应一次。
2.中间4-9 次打印,都是 “点击了” 输出多次 ,才输出一次 “我是一秒执行一次的,不要点快了哦”。 因为 前者 没有做节流处理,而后者 做了节流处理 控制了单位时间内的打印次数。让后者只能在一秒内打印一次。
3.从代码看出,我一秒点击鼠标6次或者7次,才会打印一次 “我是一秒执行一次的,不要点快了哦”,实现了节流效果。
总结
节流 是一种技术,当然我们也可以将节流 看出一种 解决特点需求的 解决方案。其最终要达到的效果就是控制某个数据流 触发的频率。实现节流的方式 当然 也不仅仅限制上述,其实现方法还有很多,只要能满足我们的需求即可。