鸿蒙NEXT开发节流、防抖工具类(ArkTs)

复制代码
import { CacheUtil } from './CacheUtil';
import { DateUtil } from './DateUtil';

/**
 * 节流、防抖工具类(用于点击事件,防止按钮被重复点击)
 *
 * @author 鸿蒙布道师
 * @since 2025/04/07
 */
export class ClickUtil {
  private static throttleTimeoutID: number | null = null; // 节流 timeout ID
  private static flag: boolean = false; // 节流标志位,true 表示已进入执行状态
  private static defaultId: string = DateUtil.getTodayTime().toString(); // 防抖默认 ID

  /**
   * 节流:在一定时间内,只触发一次
   *
   * @param func 要执行的回调函数
   * @param wait 延时的时间,默认为 1000 毫秒
   * @param immediate 是否立即执行,默认为 true
   *                  - true: 立即执行第一次调用
   *                  - false: 等待指定时间后执行
   */
  static throttle(func: () => void, wait: number = 1000, immediate: boolean = true): void {
    if (immediate) {
      // 如果未处于节流状态,则立即执行
      if (!ClickUtil.flag) {
        ClickUtil.flag = true;
        typeof func === 'function' && func();
        ClickUtil.throttleTimeoutID = setTimeout(() => {
          ClickUtil.flag = false;
          if (ClickUtil.throttleTimeoutID !== null) {
            clearTimeout(ClickUtil.throttleTimeoutID);
            ClickUtil.throttleTimeoutID = null;
          }
        }, wait);
      }
    } else {
      // 如果未处于节流状态,则等待指定时间后执行
      if (!ClickUtil.flag) {
        ClickUtil.flag = true;
        ClickUtil.throttleTimeoutID = setTimeout(() => {
          ClickUtil.flag = false;
          typeof func === 'function' && func();
          if (ClickUtil.throttleTimeoutID !== null) {
            clearTimeout(ClickUtil.throttleTimeoutID);
            ClickUtil.throttleTimeoutID = null;
          }
        }, wait);
      }
    }
  }

  /**
   * 防抖:一定时间内,只有最后一次操作,再过 wait 毫秒后才执行函数
   *
   * @param func 要执行的函数
   * @param wait 延时的时间,默认为 1000 毫秒
   * @param clickId 设置的点击事件 ID,用于区分多个点击事件,不传则使用默认 ID
   */
  static debounce(func: () => void, wait: number = 1000, clickId: string = ClickUtil.defaultId): void {
    const cacheKey = `ClickUtil_debounce_timeoutID_${clickId}`;
    const cachedTimeoutID = CacheUtil.get<number>(cacheKey); // 获取缓存的 timeout ID

    // 清除之前的定时器
    if (cachedTimeoutID !== undefined && cachedTimeoutID !== null) {
      clearTimeout(cachedTimeoutID);
    }

    // 设置新的定时器
    const timeoutID = setTimeout(() => {
      typeof func === 'function' && func();
      CacheUtil.remove(cacheKey); // 执行后清除缓存
    }, wait);

    // 缓存当前的 timeout ID
    CacheUtil.put<number>(cacheKey, timeoutID);
  }
}

代码如下:
TypeScript 复制代码
import { CacheUtil } from './CacheUtil';
import { DateUtil } from './DateUtil';

/**
 * 节流、防抖工具类(用于点击事件,防止按钮被重复点击)
 *
 * @author 鸿蒙布道师
 * @since 2025/04/07
 */
export class ClickUtil {
  private static throttleTimeoutID: number | null = null; // 节流 timeout ID
  private static flag: boolean = false; // 节流标志位,true 表示已进入执行状态
  private static defaultId: string = DateUtil.getTodayTime().toString(); // 防抖默认 ID

  /**
   * 节流:在一定时间内,只触发一次
   *
   * @param func 要执行的回调函数
   * @param wait 延时的时间,默认为 1000 毫秒
   * @param immediate 是否立即执行,默认为 true
   *                  - true: 立即执行第一次调用
   *                  - false: 等待指定时间后执行
   */
  static throttle(func: () => void, wait: number = 1000, immediate: boolean = true): void {
    if (immediate) {
      // 如果未处于节流状态,则立即执行
      if (!ClickUtil.flag) {
        ClickUtil.flag = true;
        typeof func === 'function' && func();
        ClickUtil.throttleTimeoutID = setTimeout(() => {
          ClickUtil.flag = false;
          if (ClickUtil.throttleTimeoutID !== null) {
            clearTimeout(ClickUtil.throttleTimeoutID);
            ClickUtil.throttleTimeoutID = null;
          }
        }, wait);
      }
    } else {
      // 如果未处于节流状态,则等待指定时间后执行
      if (!ClickUtil.flag) {
        ClickUtil.flag = true;
        ClickUtil.throttleTimeoutID = setTimeout(() => {
          ClickUtil.flag = false;
          typeof func === 'function' && func();
          if (ClickUtil.throttleTimeoutID !== null) {
            clearTimeout(ClickUtil.throttleTimeoutID);
            ClickUtil.throttleTimeoutID = null;
          }
        }, wait);
      }
    }
  }

  /**
   * 防抖:一定时间内,只有最后一次操作,再过 wait 毫秒后才执行函数
   *
   * @param func 要执行的函数
   * @param wait 延时的时间,默认为 1000 毫秒
   * @param clickId 设置的点击事件 ID,用于区分多个点击事件,不传则使用默认 ID
   */
  static debounce(func: () => void, wait: number = 1000, clickId: string = ClickUtil.defaultId): void {
    const cacheKey = `ClickUtil_debounce_timeoutID_${clickId}`;
    const cachedTimeoutID = CacheUtil.get<number>(cacheKey); // 获取缓存的 timeout ID

    // 清除之前的定时器
    if (cachedTimeoutID !== undefined && cachedTimeoutID !== null) {
      clearTimeout(cachedTimeoutID);
    }

    // 设置新的定时器
    const timeoutID = setTimeout(() => {
      typeof func === 'function' && func();
      CacheUtil.remove(cacheKey); // 执行后清除缓存
    }, wait);

    // 缓存当前的 timeout ID
    CacheUtil.put<number>(cacheKey, timeoutID);
  }
}
相关推荐
赏金术士1 天前
Compose 教学项目
android·kotlin·compose
晓梦林1 天前
ximai靶场学习笔记
android·笔记·学习
nashane1 天前
HarmonyOS 6学习:外接键盘CapsLock与长截图功能的实战调试与完整解决方案
学习·华为·计算机外设·harmonyos
ACP广源盛139246256731 天前
iOS 27 开放 AI 生态@ACP#小型化扩展黄金风口,IX8008全面超越 ASM2806,铸就嵌入式 AI 扩展核心
人工智能·嵌入式硬件·macos·ios·计算机外设·objective-c·cocoa
十六年开源服务商1 天前
2026服务器配置优化与WordPress运维实战指南
android·运维·服务器
人月神话Lee1 天前
【图像处理】卷积原理与卷积核——图像处理的核心引擎
ios·ai编程·图像识别
音视频牛哥1 天前
大牛直播SDK(SmartMediaKit)Android平台Unity3D RTSP/RTMP播放器集成实践
android·unity3d·rtsp播放器·rtmp播放器·unity3d rtmp播放器·安卓unity rtsp播放器·安卓unity rtmp播放器
w1wi1 天前
安卓抓包完全指南(一):从入门到 SSL Pinning 绕过
android·网络协议·ssl
用户223586218201 天前
如何在超大型的工程中使用 Claude Code?
前端·ios·claude