一个关于闭包防抖的疑惑,望朋友们赐教,感谢:
function fangdou(callback,time){
let timeout
return function(){
if(timeout) clearTimeout(timeout)
timeout = setTimeout(callback, time);
}
}
function con(){
console.log('发起请求')
}
document.addEventListener('input',fangdou(con,2000))
input框输入停止后2s才打印。这个是能够正常实现的,但是如果我改写成:
function fangdou2(){
let timeout
return function(callback,time){
if(timeout) clearTimeout(timeout)
timeout = setTimeout(callback, time);
}
}
function con2(){
console.log('发起请求2')
}
const foo = fangdou2()
document.addEventListener('input',foo(con2,2000))
只是用foo将函数fangdou2先执行了拿到了闭包函数,监听input框时执行foo。但是会出现第一次加载页面时就会自动打印'发起请求2‘’,这个为什么呢?
还有,input框中输入也不会触发函数con2?
该回答引用GPTᴼᴾᴱᴺᴬᴵ
第一个问题是因为在执行 fangdou2() 时,函数内的代码会被执行一次,导致 timeout 已经被定义为 undefined,所以 if(timeout) 判断条件不成立,直接执行了 setTimeout(callback, time),因此在页面加载时就会自动打印一次。
-
为了避免这种情况,可以将 timeout 的初始值设置为 null,这样在第一次调用 callback 前判断 if(timeout !== null) 会返回 false,避免了自动执行 callback 的问题。
-
第二个问题是因为在 fangdou2() 函数中,闭包函数接收的是 callback 和 time 参数,但在监听 input 事件时,传入的参数却是 con2 和 2000。这样虽然能够解决 timeout 的问题,但无法正常触发函数。可以考虑将 con2 和 2000 作为参数传入闭包函数中,而不是作为监听器函数的参数。修改后的代码如下:
function fangdou2() {
let timeout = null;
return function(callback, time) {
if (timeout !== null) clearTimeout(timeout);
timeout = setTimeout(callback, time);
}
}
function con2() {
console.log('发起请求2');
}
const foo = fangdou2();
document.addEventListener('input', function() {
foo(con2, 2000);
});
这样就能正常触发函数了。