点击上方☝Java编程技术乐园,轻松关注!及时获取有趣有料的技术文章
文章很好,耐心阅读,记得点赞和关注哦~
前言
最近有个朋友在面试过程中遇到一个问题:什么是防抖和节流?糟了,这可触碰到我的知识盲区了,好像听也没听过这 2 个东西,痛定思痛,赶紧学习学习。
防抖(debounce)
在事件被触发 n 秒之后执行,如果在此期间再次触发事件,则重新开始计时。
乍一看,这不是闲的蛋疼吗?为啥要等 n 秒之后再执行呢?
本着存在即合理的原则,咱看不懂但咱得去学啊!经过十秒钟的思考,突然想起来之前做过的公司的一个小程序,使用的 mpvue+vant-weapp,van-field 标签并没有和数据进行双向绑定,而是每次都要触发 @input 事件,从而完成数据绑定:
这就导致了一个问题:
输一个手机号要触发 11 次事件!!如果是联想搜索的话。。。那画面太美!
我们先自己想一下办法来解决这个问题。
- 首先我们需要在手机号输入完成之后将数据绑定到 phoneNumber 上然后进行联想搜索,怎么算输入完成呢,输入一个数字到找到下一个数字输入大概需要 1 不到秒,只要用户一秒内没有再次输入,则将输入框内容与 phoneNumber 绑定并进行联想搜索(什么?你说你输入五个字符就停下?不怕后台砍死你)。
- 准备工具:一个需要触发的函数 debounce、一个定时器、一个输入框、一个判断是否输入完成的函数 getPhone。
- 基本思路:输入绑定事件 getPhone,输入之后开启1秒定时器,如果在 1 秒内再次进行了输入,则清除之前的定时器,并且重新设置定时器;如果 1 秒内没有输入,则输入结束触发事件 a,进行联想搜索。
// 需要触发的函数function debounce(d){ console.log("联想搜索phoneNumber:" + d)}let inp = document.querySelector("#phone");// 输入触发的事件function getPhone(fn,delay){ let timer; // 使用闭包,保证每次使用的定时器是同一个 return (d)=>{ clearTimeout(timer); timer = setTimeout(()=>{ fn(d); // 结束之后清除定时器 clearTimeout(timer); },delay) }}let getPhoneDebounce = getPhone(debounce,1000);inp.addEventListener('keyup',(e)=>{ getPhoneDebounce(e.target.value);})
这时候看输出:
是的只输出了一次号码,也就是说不用每次输入都进行一次搜索了。
节流(throttle)
如果持续触发一个事件,则在一定的时间内只执行一次事件。
那么问题来了,既然是持续触发了,那为啥还要设定一定时间内只执行一次呢?废话,你吃鸡为啥不用 AKM 非要去追梦抢狗杂呢?还不是因为 AKM 射速慢(狗杂真香)!
我们来试着做一个 AKM 的设计模拟:
- 首先第一次点击射击的时候,打出一发子弹,当以极短的时间再次点击射击的时候,由于需要‘冷却’——也就是节流,再次点击无效,当冷却时间过了之后,再次点击射击,则继续下一次射击。
- 准备工具:一个射击的函数 shot,一个判断射击间隔是否结束的函数 nextShot,一个触发射击的按钮,判断射击是否结束的定时器 timer。
- 基本思路:第一次点击按钮的时候,触发 shot,当继续点击的时候,射击无效,只有过了定时器设置的时间才可以继续射击。
射击
function shot(){ console.log('射击')}let btn = document.querySelector('#shot');function nextShot(fn,delay){ let timer; // 闭包原理同上 return ()=>{ // 定时器存在,无法射击 if(timer){ console.log('禁止射击'); }else{ // 定时器不存在,射击,并设置定时器 fn(); timer = setTimeout(()=>{ // 定时器结束,可以射击 clearTimeout(timer); timer = null; },delay) } }}let start = nextShot(shot,20);btn.addEventListener('click',()=>{ start();})
当我们疯狂点击按钮的时候:
可能这个例子不是很突出,我再说个类似的,英雄联盟和DNF的技能冷却应该更适合~
是时候回归一下标题了,免得有人说我可以去 UC 震惊部了!公司的大数据组件目前是只要页面大小发生变化就会重新加载,这就导致了有时候拉一下控制台会发生很多次请求,这个时候就可以用防抖来解决一下了~
作者:.Ping
链接:https://juejin.im/post/5e0d7ab9f265da5d691035b5
来源:掘金