鸿蒙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 小时前
Android第六次面试总结之Java设计模式(二)
android·java·面试
安和昂4 小时前
【iOS】 方法交换
macos·ios·cocoa
北执南念6 小时前
IDEA回滚代码操作
android·java·intellij-idea
蓝桉柒76 小时前
PHP分页显示数据,在phpMyadmin中添加数据
android·ide·android studio
美狐美颜sdk7 小时前
什么是美颜SDK?美颜SDK安卓与iOS端开发指南
android·人工智能·ios·音视频·美颜sdk·直播美颜sdk
IT小饕餮7 小时前
华为私有协议Hybrid
运维·服务器·华为
n33(NK)8 小时前
MySQL 窗口函数入门到精通
android·数据库·mysql
撸码到无法自拔8 小时前
android Kotlin ,internal class , data class, class的区别
android·java·开发语言·kotlin
jcsx9 小时前
【mysql】常用命令
android·数据库·mysql
青年夏日科技工作者9 小时前
Android WebView加载h5打开麦克风与摄像头的权限问题
android·数码相机·harmonyos