zhxy-jzd/src/utils/debounce.ts
2025-09-02 20:57:37 +08:00

107 lines
2.4 KiB
TypeScript

// src/utils/debounce.ts
import { ref } from 'vue';
/**
* 通用防抖函数
* @param func 需要防抖的函数
* @param delay 延迟时间(毫秒)
* @param immediate 是否立即执行
* @returns 防抖后的函数
*/
export function debounce(func: Function, wait: number, immediate: boolean = false) {
let timeout: NodeJS.Timeout | null;
return function (this: any, ...args: any[]) {
const context = this;
const later = function () {
timeout = null;
if (!immediate) func.apply(context, args);
};
const callNow = immediate && !timeout;
if (timeout) clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
/**
* 防抖状态管理类
* 用于管理多个防抖状态
*/
export class DebounceManager {
private states: Map<string, boolean> = new Map();
/**
* 设置防抖状态
* @param key 状态标识
* @param value 状态值
* @param duration 状态持续时间(毫秒)
*/
setState(key: string, value: boolean, duration?: number): void {
this.states.set(key, value);
if (value && duration) {
setTimeout(() => {
this.states.set(key, false);
}, duration);
}
}
/**
* 获取防抖状态
* @param key 状态标识
* @returns 状态值
*/
getState(key: string): boolean {
return this.states.get(key) || false;
}
/**
* 重置所有状态
*/
reset(): void {
this.states.clear();
}
}
/**
* Vue组合式API防抖函数
* @param delay 延迟时间(毫秒)
* @returns 包含防抖状态和控制函数的对象
*/
export function useDebounce(delay: number = 1000) {
const isProcessing = ref(false);
const debounce = <T extends (...args: any[]) => Promise<any>>(
func: T
): ((...args: Parameters<T>) => Promise<ReturnType<T> | void>) => {
return async (...args: Parameters<T>): Promise<ReturnType<T> | void> => {
// 如果正在处理中,则阻止新的调用
if (isProcessing.value) {
return;
}
isProcessing.value = true;
try {
const result = await func(...args);
return result;
} finally {
// 延迟重置状态,防止快速重复点击
setTimeout(() => {
isProcessing.value = false;
}, delay);
}
};
};
const reset = () => {
isProcessing.value = false;
};
return {
isProcessing,
debounce,
reset
};
}