本文共 2408 字,大约阅读时间需要 8 分钟。
一、前言
为什么会有去抖和节流这类工具函数?
在用户和前端页面的交互过程中,很多操作的触发频率非常高,比如鼠标移动 mousemove 事件, 滚动条滑动 scroll 事件, 输入框 input 事件, 键盘 keyup 事件,浏览器窗口 resize 事件。
在以上事件上绑定回调函数,如果回调函数是一些需要大量计算、消耗内存、HTTP 请求、DOM 操作等,那么应用的性能和体验就会非常的差。
去抖和节流函数的根据思想就是,减少高频率事件处理函数 handler 的执行频率(注意是事件处理函数,不是事件回调函数),将多次事件的回调合并成一个回调来执行,从而优化性能。
二、简单版去抖(debounce)
去抖(debounce),也叫防抖,那抖动指的是什么呢?抖动意味着操作的不稳定性,你可以理解成躁动症,安静不下来~防抖的含义便是为了防止抖动造成的结果不准确,等到稳定的时候再处理结果。
比如在输入事件,鼠标移动,滚动条滑动,键盘敲击事件中,等到停止事件触发,频率稳定为零后,才开始执行回调函数,也就是所谓的没有抖动后处理。
个人总结:去抖,就是事件触发频率稳定后,才开始执行回调函数, 一连串的事件触发,但只进行一次事件处理。
频率就是单位时间触发的次数,如果单位时间内,事件触发超过一次,就只执行最后一次,如果单位时间内没有触发超过一次,那就正常执行。去抖分为延迟执行和立即执行两种思路。
看一个简单版的去抖函数延迟执行实现:
输入框:复制代码
上面代码中我的注释已经能够说明整个去抖的过程,再来啰嗦几句话~
以上就是去抖函数的基本思想, 可以参考示意图
下面这张图是高设 3 里讲的节流函数,其实是这一节所说的去抖函数,高设 3 将 timer 变量用传入的处理函数的属性代替了而已。
三、立即执行
第二节的简单版去抖函数能满足大部分只需要触发一次事件处理的去抖场景:输入框输入关键字查询搜索结果。
但是有一个问题,假如我想输入框输入内容时,第一个字输完就请数据怎么做? 你可以理解为,你可以马上开始说话,但是说完话后 5 分钟不能说话,如果 5 分钟内说话,则接下来再加 5 分钟不能说话。如果 5 分钟后没说话, 那么接下来,你又可以先说话,然后闭嘴 5 分钟~
所以,引出来了立即执行版的去抖函数。
取消功能实现
输入框:复制代码
上面代码的注释,可以解释整个流程,下面大致说一下:
看看效果:
取消函数
假如去抖函数的间隔时间为 5 秒钟,我在这 5 秒钟内又想立即执行可以怎么做?于是我们给回调函数加个取消函数属性。
函数也是一个对象,可以像其他一般对象那样添加方法:
输入框:复制代码
看看效果:
总结
去抖函数的意义在于合并多次事件触发为一次事件处理,从而降低事件处理函数可能引发的大量重绘重排,http 请求,内存占用和页面卡顿。
另外,本文有关 this, call, apply,闭包的知识,可以翻看我之前分享的文章。
欢迎关注我的个人公众号“谢南波”,专注分享原创文章。
掘金专栏 JavaScript 系列文章