You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 16:15:02