鸿蒙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);
  }
}
相关推荐
csdn12259873362 分钟前
JetPack Compose 入门先搞清楚
android·compose·jetpack
liang_jy29 分钟前
Android LaunchMode
android·面试
萌虎不虎1 小时前
【鸿蒙实现显示屏测试实现方法】
华为·harmonyos
阿里云云原生2 小时前
Android App 崩溃排查实战:如何利用 RUM 完整数据与符号化技术定位问题?
android·阿里云·云原生·rum
sweet丶2 小时前
UIWindowScene 使用指南:掌握 iOS 多窗口架构
ios
过期动态2 小时前
JDBC高级篇:优化、封装与事务全流程指南
android·java·开发语言·数据库·python·mysql
用户5951433221774 小时前
HarmonyOS应用开发之滚动容器Scroll
harmonyos
用户5951433221774 小时前
HarmonyOS应用开发之瀑布流、上拉加载、无限滚动一文搞定
harmonyos
用户5951433221774 小时前
鸿蒙应用开发之@Builder自定义构建函数:值传递与引用传递与UI更新
harmonyos
没有了遇见4 小时前
Android 音乐播放器之MotionLayout实现View流畅变换
android