鸿蒙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);
  }
}
相关推荐
Jomurphys14 分钟前
设计模式 - 适配器模式 Adapter Pattern
android
雨白19 分钟前
电子书阅读器:解析 EPUB 底层原理与实战
android·html
g***B73820 分钟前
Kotlin协程在Android中的使用
android·开发语言·kotlin
Z***u65930 分钟前
HarmonyOS在智能穿戴中的运动识别
华为·harmonyos
柒儿吖30 分钟前
Electron for 鸿蒙PC - Webpack PublicPath 动态设置完整方案
webpack·electron·harmonyos
A***279532 分钟前
Kotlin反射机制
android·开发语言·kotlin
2501_9160074733 分钟前
iOS 应用性能测试的工程化流程,构建从指标采集到问题归因的多工具协同测试体系
android·ios·小程序·https·uni-app·iphone·webview
爱笑的眼睛1134 分钟前
HarmonyOS 跨设备迁移与协同:深入技术实现与创新应用
华为·harmonyos
源码_V_saaskw35 分钟前
JAVA国际版同城跑腿源码快递代取帮买帮送同城服务源码支持Android+IOS+H5
android·java·ios·微信小程序
q***d1731 小时前
Kotlin在后台服务中的框架
android·开发语言·kotlin