TS版的防抖函数(严格的类型推断)
export function isFunction(obj: any): obj is Function {
return typeof obj === "function";
}
type fnType<T> = (...args: T[]) => any;
type successCallbackType<T = any> = (...args: T[]) => any;
type failCallbackType<T = any> = (...args: T[]) => any;
export function debounce<T = any, V = any>(
fn: fnType<T>,
delay: number = 200,
immediate: boolean = false,
successCallback?: successCallbackType<V>,
failCallback?: failCallbackType<V>
) {
let timer: any = null;
let isInvoke = false;
const doWithCatch = (
callback: fnType<T>,
resolve: (value: T | PromiseLike<T>) => void,
reject: (reason?: any) => void,
...params: T[]
) => {
try {
const res = callback.call(this, ...params);
if (isFunction(successCallback)) successCallback(res);
resolve(res);
} catch (err: any) {
isInvoke = true;
reject(err);
if (isFunction(failCallback)) failCallback(err);
}
};
const _debounce = function (...params: T[]) {
return new Promise<T>((resolve, reject) => {
if (timer) clearTimeout(timer);
if (!isInvoke && immediate) {
let res: any;
try {
res = fn.call(this, ...params);
} catch (error: any) {
isInvoke = true;
reject(error);
if (isFunction(failCallback)) failCallback(error);
}
isInvoke = true;
resolve(res);
if (isFunction(successCallback)) successCallback(res);
} else {
timer = setTimeout(() => {
doWithCatch(fn, resolve, reject, ...params);
isInvoke = false;
timer = null;
}, delay);
}
});
};
_debounce.cancel = () => {
clearTimeout(timer);
timer = null;
isInvoke = false;
};
return _debounce;
}
|