概念
debounce
字面理解是“防抖”,何谓“防抖”,就是连续操作结束后再执行,以网页滚动为例,debounce要等到用户停止滚动后才执行,将连续多次执行合并为一次执行。
throttle
字面理解是“节流”,何谓“节流”,就是确保一段时间内只执行一次,以网页滚动为例,throttle是如果用户一直在滚动网页,那么在滚动过程中还是会执行,只是一段时间内只执行一次,将连续执行的间隔变大了。
实现
debounce
第一次触发后,进行倒计wait毫秒,如果倒计时过程中有其他触发,则重置倒计时;否则执行。
throttle
第一次触发后先执行fn(lodash可以通过{leading: false}来取消),然后wait ms后再次执行,在单位wait毫秒内的所有重复触发都被抛弃。
应用场景
debounce
用来丢弃一些重复的密集操作,直到流量减慢。
throttle
用在每隔一定间隔执行回调的场景,即如果有连续不断的触发,每wait ms执行fn一次。
场景举例
debounce
- ajax 请求合并,不希望短时间内大量的请求被重复发送
- mouse move 时减少计算次数
- resize window 重新计算样式或布局
throttle
- resize window 重新计算样式或布局
- scroll 时触发操作,如随动效果:throttle
- 对用户输入的验证,不想停止输入再进行验证,而是每n秒进行验证
图片说明
在参考了RxJS官网的描述后,觉得豁然开朗,用图片说明最清晰
假设一个数据源每隔一秒发送一个数,而我们使用了debounceTime操作符,并设置了延时时间,那么在数据源发送一个新数据之后,如果在延时时间内数据源又发送了一个新数据,这个新的数据就会被先缓存住不会发送,等待发送完数据之后并等待延时时间结束才会发送给订阅者,不仅如此,在延时时间未到的时候并且已有一个值在缓冲区,这个时候又收到一个新值,那么缓冲区就会把老的数据抛弃,放入新的,然后重新等待延时时间到达然后将其发送。
该操作符主要能力跟我们认知的节流函数也是一致的,就是它会控制一定时间内只会发送一个数据,多余的会直接抛弃掉。唯一和防抖操作符不一致的地方就在于它对于第一个值是不会阻塞的。