当前位置:首页 > JavaScript

js 装饰器实现防抖

2026-04-04 22:54:19JavaScript

使用装饰器实现防抖

防抖(Debounce)是一种常见的技术,用于限制函数在短时间内频繁触发。通过装饰器(Decorator)可以优雅地实现这一功能。

基础防抖装饰器

function debounce(delay) {
  let timeoutId;
  return function(target, key, descriptor) {
    const originalMethod = descriptor.value;
    descriptor.value = function(...args) {
      clearTimeout(timeoutId);
      timeoutId = setTimeout(() => {
        originalMethod.apply(this, args);
      }, delay);
    };
    return descriptor;
  };
}

使用方式:

js 装饰器实现防抖

class MyClass {
  @debounce(300)
  handleInput() {
    console.log('Input handled after debounce');
  }
}

立即执行版本

有时需要首次调用立即执行,后续调用才进行防抖:

js 装饰器实现防抖

function debounceImmediate(delay) {
  let timeoutId;
  let shouldCall = true;
  return function(target, key, descriptor) {
    const originalMethod = descriptor.value;
    descriptor.value = function(...args) {
      if (shouldCall) {
        originalMethod.apply(this, args);
        shouldCall = false;
      }
      clearTimeout(timeoutId);
      timeoutId = setTimeout(() => {
        shouldCall = true;
      }, delay);
    };
    return descriptor;
  };
}

带取消功能的防抖

function debounceWithCancel(delay) {
  let timeoutId;
  return function(target, key, descriptor) {
    const originalMethod = descriptor.value;
    descriptor.value = function(...args) {
      clearTimeout(timeoutId);
      timeoutId = setTimeout(() => {
        originalMethod.apply(this, args);
      }, delay);
    };

    // 添加取消方法
    descriptor.value.cancel = function() {
      clearTimeout(timeoutId);
    };

    return descriptor;
  };
}

使用方式:

const instance = new MyClass();
instance.handleInput(); // 正常调用
instance.handleInput.cancel(); // 取消待执行的调用

TypeScript 版本

对于 TypeScript 项目,可以添加类型声明:

function debounceTS(delay: number) {
  let timeoutId: ReturnType<typeof setTimeout>;
  return function(
    target: any,
    key: string,
    descriptor: PropertyDescriptor
  ) {
    const originalMethod = descriptor.value;
    descriptor.value = function(...args: any[]) {
      clearTimeout(timeoutId);
      timeoutId = setTimeout(() => {
        originalMethod.apply(this, args);
      }, delay);
    };
    return descriptor;
  };
}

注意事项

  • 装饰器目前是 ECMAScript 的提案,需要使用 Babel 插件 @babel/plugin-proposal-decorators 进行转译
  • 在类方法中使用时,this 绑定是正确的
  • 防抖时间应根据实际场景调整,通常 200-500ms 适用于用户输入场景
  • 多次快速调用时,只有最后一次调用会实际执行

标签: 防抖js
分享给朋友:

相关文章

jquery.js

jquery.js

jQuery 是一个快速、简洁的 JavaScript 库,简化了 HTML 文档遍历、事件处理、动画设计和 Ajax 交互等操作。以下是关于 jQuery.js 的核心信息和使用方法: 获取 jQ…

js 实现vue

js 实现vue

Vue.js 的基本实现 在 JavaScript 中实现 Vue.js 的核心功能,可以通过数据绑定、响应式系统和虚拟 DOM 来实现。以下是实现 Vue.js 核心功能的简化版本。 数据响应式系…

js手势实现

js手势实现

手势识别实现方法 在JavaScript中实现手势识别通常涉及监听触摸事件(touchstart、touchmove、touchend)或鼠标事件(mousedown、mousemove、mouseu…

js实现导航菜单

js实现导航菜单

使用HTML和CSS创建基础结构 导航菜单的基础结构通常由HTML的无序列表(<ul>)和列表项(<li>)组成,每个列表项包含一个链接(<a>)。CSS用于样式化…

实现图片旋转js

实现图片旋转js

使用CSS transform属性旋转图片 通过CSS的transform属性可以轻松实现图片旋转。以下是一个简单的示例代码: const image = document.getElement…

js实现刷新页面

js实现刷新页面

刷新页面的方法 在JavaScript中,可以通过多种方式实现页面刷新。以下是几种常见的方法: 使用 location.reload() 调用 location.reload() 方法可以重新加载当…