当前位置:首页 > 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;
  };
}

使用方式:

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

立即执行版本

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

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 项目,可以添加类型声明:

js 装饰器实现防抖

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
分享给朋友:

相关文章

js实现全屏

js实现全屏

实现全屏的基本方法 使用JavaScript实现全屏功能主要依赖Element.requestFullscreen()方法。现代浏览器均支持此API,但不同浏览器可能需要添加前缀。 // 触发全屏…

js实现复制功能

js实现复制功能

使用 document.execCommand 方法 这种方法适用于较旧的浏览器,但在现代浏览器中可能被逐步淘汰。通过创建一个临时的 textarea 元素,将文本内容放入其中,然后执行复制命令。…

js轮播图实现原理

js轮播图实现原理

轮播图的基本原理 轮播图通过动态切换显示的内容(图片、文本等)实现视觉上的滑动效果。核心原理是利用CSS和JavaScript控制元素的显示与隐藏,或通过变换位置实现滑动动画。 实现方法一:CSS…

js实现换肤

js实现换肤

使用CSS变量实现换肤 通过CSS变量可以轻松实现主题切换功能。CSS变量在根元素中定义,通过JavaScript动态修改这些变量值。 :root { --primary-color: #349…

js实现预览

js实现预览

文件上传预览实现 使用JavaScript实现文件上传预览功能,可以通过FileReader对象读取文件内容并显示预览。以下代码支持图片、文本和PDF文件的预览: // HTML部分需要包含…

js实现二叉树

js实现二叉树

二叉树的基本概念 二叉树是一种树形数据结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树的常见操作包括插入、删除、遍历等。 二叉树的节点定义 在JavaScript中,二叉树的节点可…