JS防抖函数中console.log("Called")为何仅执行一次?
现象成因
该现象是函数执行时机与事件绑定逻辑不匹配导致的,具体逻辑如下:
addEventListener绑定事件时,第二个参数需要传入事件触发时执行的函数引用。代码中传入的debounce(callback,700)是立即执行的函数调用,而非debounce函数本身。- 代码初始化运行到事件绑定语句时,会立刻执行一次
debounce(callback,700):此时会进入debounce函数体,创建闭包变量time、执行一次console.log("Called"),最终返回内部定义的匿名函数。 - 后续每次
keyup事件触发时,实际执行的是debounce返回的这个内部匿名函数,不会重新运行debounce的外层函数逻辑。你将打印语句写在了debounce的外层函数作用域中,没有放在实际绑定给事件的闭包函数内,因此只会在初始化绑定阶段打印一次,不会随每次按键触发重复打印。
验证&修正方法
当前防抖的核心节流逻辑本身是正常生效的,如果需要每次触发keyup时都打印日志,把console.log("Called")移动到debounce返回的内部函数中即可,修正后的代码片段:
function debounce(fun,delay) { let time; return function(args) { console.log("Called"); // 移至此处即可随每次事件触发打印 if(time) { clearTimeout(time); } time = setTimeout(() => { fun(args); },delay); } }
补充:防抖本质是高阶函数,作用是执行一次后生成持有闭包变量的实际事件处理函数,本身就不应该随每次事件触发重复执行。
内容的提问来源于stack exchange,提问作者Ankur Kashyap
相关产品推荐
相关产品推荐

