Vue组件中JavaScript Debounce防抖函数未清除队列问题咨询
防抖失效原因
你当前的写法每次触发searchboxChange事件时,都会重新执行common.debounce()生成一个全新的防抖函数,每个新函数会独立持有自己的timer变量,前一次触发生成的定时器无法被后续触发的事件清除,最终所有定时器超时后会批量执行回调,导致防抖失效。
解决方案
- 方案1:提前实例化防抖函数(推荐)
在Vue实例初始化阶段就生成防抖后的回调函数,事件直接绑定该函数即可,无需每次触发事件时重新生成。
import common from "@/assets/js/Service/Common"; export default { // 其余配置省略 created() { // 提前生成防抖后的函数,挂到实例上,全程复用同一个实例 this.debouncedFilterChange = common.debounce(() => this.filterChanged(), 1000) }, methods: { filterChanged() { // 原有搜索逻辑 } } }
模板绑定修改为:
<input @keyup="debouncedFilterChange">
- 方案2:懒加载防抖函数
如果要保留searchboxChange方法的封装逻辑,也可以把生成的防抖函数存到实例属性中,避免重复生成:
methods: { searchboxChange(){ // 仅首次触发时生成防抖函数,后续复用 if(!this._debouncedFn) { this._debouncedFn = common.debounce(() => this.filterChanged(), 1000) } this._debouncedFn() } }
注意事项
组件销毁前建议清除未执行的定时器,避免内存泄漏,可以先给公共库的防抖函数增加取消方法:
// common.js 中的debounce修改 debounce(func, timeout = 300) { let timer; const debounced = (...args) => { clearTimeout(timer); timer = setTimeout(() => { func.apply(this, args); }, timeout); }; // 挂载取消方法 debounced.cancel = () => clearTimeout(timer) return debounced }
在组件销毁钩子中调用取消方法:
beforeDestroy() { this.debouncedFilterChange?.cancel() // 如果用方案2则写 this._debouncedFn?.cancel() }
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

