Debounce
首先先聊聊防抖吧
-
定义:
把多次请求合并成一个请求,这多个请求其实都会被调用,但只有其中的一个会被完整地正确地执行。
-
当然你可能会想问被合成地这一个请求,它出现的时间点是什么?
分为两种情况:
- (Leading options) 出现在第一个请求,然后后面的请求就会被合成为这一个请求
- (Trailing options) 出现在最后一个请求后的一段时间,就是之前的所有的请求都会被合成为这一个请求
- (注意这里的
后的一段时间,只有 Trailing Options 有这个限制,Leading Options 没有这个限制 )
-
那它一般是有什么运用场景捏?
一般是在用在处理短时间多次触发的 (代价较大的 如时间和资源消耗较大的 等等) 操作上,如:
- 短时间内多次按钮点击,而只想该按钮触发一次,如某个按钮点击后会发起一个请求,而设计时想节省和保护服务器资源,就会将短时间多次触发的请求合成为一个
- 还有比如说,输入自动补全或者是提示,只有当输入停止时才会触发,而当持续输入时则不会被触发
-
那最简单,最基本的实现方法是什么捏?
下面展示的 Trailing Options的实现方式⬇️:
const debounce = (fn, delay) => { let timeoutId; return function(...args) { if(timeoutId) { clearTimeout(timeoutId); } timeoutId = setTimeout(() => { fn(...args); }, delay) } }-
首先看下最外层
debounce 这个箭头函数接受两个参数 一个是
fn即想要被 debounce 化的函数; 还有一个是delay可以理解为 上文第二点 中提到的后的一段时间,或者可以理解为超出这段时间的再次调用,不会参与到和上次调用相关的合并中去。
-
然后再看下内层
这里是使用闭包,使得被返回的函数记住
timeoutId这个变量。
-
然后看下被返回的函数
是在原本要调用的函数外再加一层,首先对
timeoutId进行刷新,其实就是将之前的setTimeout清除,重新设置一个timeout大于delay(debouce传进来的第二个参数)。
- 通过这些操作,我们就得到了
debounce函数,经过它的处理,连续的调用实际上都会被合并成一个函数,(这里实现的是Trailing Options型的,所以被合并的调用会出现在连续调用的最后一次调用的一段时间后 即传入的delay值)。
-