zhxy-jzd/src/utils/debounce.ts

107 lines
2.4 KiB
TypeScript
Raw Normal View History

2025-09-02 20:57:37 +08:00
// 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
};
}