debounce: Grouping a sudden burst of events (like keystrokes) into a single one. throttle: Guaranteeing a constant flow of executions every X milliseconds.
The main difference between throttling and debouncing is that throttle guarantees the execution of the function regularly, at least every X milliseconds.
一、前言
在前一篇文章揭秘了
keep-alive
的实现原理:彻底揭秘keep-alive原理,本文将模拟keep-alive
原理实现Vue的防抖和节流组件。本文介绍内容包含:防抖与节流碎碎念
网上有很多关于防抖与节流定义、应用及实现的介绍,但同时也有很多不同的解释版本,特别在概念的定义理解上,就有很多的偏差,有时候我看多了网上的介绍,自己也犯晕。以下是我所认同的版本:
即:
防抖
,譬如快速点击10次登录按钮(突发10次点击事件),通过防抖操作将其归组为一次点击事件。节流
,譬如鼠标滚动事件,通过节流操作限制每50ms执行一次鼠标滚动事件。二、防抖&节流组件特性
以下表格第一列表示特性项目,
keep-alive
列是通过keep-alive源码分析得出的结论,Debounce
和Throttle
列则是我们需要模拟实现的特性效果。三、用法
Vue.component('Debounce', Debounce) Vue.component('Throttle', Throttle)
该例表示给
input
元素的input
事件添加节流效果,节流时间间隔为默认值300ms
。include
和exclude
参数的用法与keep-alive
相同,可以是String
、Array
、Regexp
中的任意类型;time
声明时间间隔;before
为钩子函数。四、手撕Throttle
定义
Throttle
组件的基本属性设置
abstract
将其定义为抽象组件,使得构建组件树的时候将其忽略;props
定义组件支持的所有参数。定义
Throuttle
组件的钩子created
钩子里面初始化缓存变量:originMap
缓存原始事件函数(节流前),throttleMap
缓存节流后的事件函数,default
缓存默认节流的事件类型,_vnode
缓存节流组件包裹的子组件;mounted
钩子里面设置include
和exclude
两个参数的监听事件;destroyed
钩子销毁变量。看一下
pruneThrottle
和matchs
针对已经节流化的事件进行去节流操作,
matchs
里面定义匹配逻辑:支持字符串、数组和正则三种类型的匹配。最后看
render
的定义:核心逻辑是,先获取第一个被包裹的子组件实例及其定义的全部事件类型;其次根据子组件的
tag
设置默认节流的事件类型(input
元素是input
事件,button
元素是click
事件);接着经过黑白名单的匹配规则后,将指定的事件函数通过throttle
函数节流化。再看
throttle
的定义:核心逻辑就是,设置一个等待事件,在这等待时间内,通过闭包变量
isInvoking
控制,指定时间内只执行一次函数。五、一网打尽:Debounce
Emmm...其实Debounce的实现原理与Throttle完全一样,只是代码上有一些差异,详细实现看代码即可:Demo