关于防抖函数的一个问题,希望得到解惑😭
function debounce(func, delay) {
let timeout
return function() {
clearTimeout(timeout) // 如果持续触发,那么就清除定时器,定时器的回调就不会执行。
timeout = setTimeout(() => {
func.apply(this, arguments)
}, delay)
}
}
function sayHi() {
console.log("防抖成功");
}
debounce(sayHi, 2000, false)()
debounce(sayHi, 2000, false)()
debounce(sayHi, 2000, false)()
debounce(sayHi, 2000, false)()
这一段防抖函数是一个网上最基础的函数,看了一下,基本上都是这么写的。
我对防抖函数的理解是多次触发,应该只响应一次,即这段代码中,应该只打出一个sayHi。但是在实际写代码的情况下,会在两秒后同时出现四个sayHi,于是怀疑防抖没有生效,只是延迟了两秒一起触发了而已
然后加入了一些settimeout来验证
function debounce(func, delay) {
let timeout
return function() {
clearTimeout(timeout) // 如果持续触发,那么就清除定时器,定时器的回调就不会执行。
timeout = setTimeout(() => {
func.apply(this, arguments)
}, delay)
}
}
function sayHi() {
console.log("防抖成功");
}
debounce(sayHi, 2000, false)()
setTimeout(debounce(sayHi, 2000, false),1000)
setTimeout(debounce(sayHi, 2000, false),3000)
setTimeout(debounce(sayHi, 2000, false),5000)
结果确实是异步在2,3,5,7秒触发了sayHi
因此有了这个疑问,是我的理解有误还是使用该函数有误呢,望有哥们儿解答。
你调用的方式错了。应该这样调用
function debounce(func, delay) {
let timeout
return function() {
clearTimeout(timeout) // 如果持续触发,那么就清除定时器,定时器的回调就不会执行。
timeout = setTimeout(() => {
func.apply(this, arguments)
}, delay)
}
}
function sayHi() {
console.log("防抖成功");
}
let a = debounce(sayHi, 2000, false);
a();
a();
a();
a();
这个防抖函数是为了在多处地方同时使用,而且互相不影响,采用了闭包对里面的func, delay参数和 timeout 定时器id进行了封装。
debounce()函数每次调用都会产生一个新的闭包。每个闭包中都有一个timeout变量和一个子函数。
debounce(sayHi, 2000, false)();
debounce(sayHi, 2000, false)();
debounce(sayHi, 2000, false)();
debounce(sayHi, 2000, false)();
这样是调用debounce()函数4次。产生4个新的闭包,4个闭包中定时器都是独立的,用clearTimeout(timeout) 只能清除自己闭包中的定时器。
4个闭包中的timeout变量初始都是null,自然无法清除定时器。导致4个闭包中的定时器同时运行。
应该这样调用
let a = debounce(sayHi, 2000, false);
debounce()函数只调用一次,只产生了一个闭包,只有一个timeout变量和一个子函数。
a是从这个闭包中返回的子函数。
a();
a();
a();
a();
这样4次调用的是同一个闭包中的子函数,4次用clearTimeout(timeout)访问的是同一个闭包中的timeout变量。
就可以清除自己闭包中的上一次的定时器,保持同时只有一个定时器在运行
如有帮助,望采纳!谢谢!