export function useStableCallback<Args extends any[], T>(fn: (...args: Args) => T) {
const fnRef = useRef(fn);
useLayoutEffect(() => {
fnRef.current = fn;
});
return useCallback((...args: Args) => fnRef.current(...args), []);
}
export function useDebounce<Args extends any[], T>(
func: (...args: Args) => T,
wait?: number,
options?: DebounceSettings
) {
const funcRef = useRef<(...args: Args) => T>(func);
const debouncedFunc = useRef(
debounce(
(...args: Args) => {
// 先以一个固定的方法绑定,再在这个方法中执行 func,此时得到的 func 永远是最新的
return funcRef.current(...args);
},
wait,
options
)
).current;
useLayoutEffect(() => {
funcRef.current = func;
});
return useCallback(debouncedFunc, [debouncedFunc]);
}
interface Deferred<T = any> {
promise: Promise<T>;
resolve: (value: T) => void;
reject: (reson?: any) => void;
}
export function useDebouncePromise<Args extends any[], R extends any = any>(
func: (...args: Args) => Promise<R>,
wait?: number,
options?: DebounceSettings
) {
function defer<T extends any>() {
let deferred: Deferred<T> = {} as any;
deferred.promise = new Promise<T>((resolve, reject) => {
deferred.resolve = resolve;
deferred.reject = reject;
});
return deferred;
}
const deferred = useRef<Deferred>(defer<Args>());
const funcRef = useRef<(...args: Args) => Promise<R>>(func);
const debouncedFunc = useRef(
debounce(
(...args: Args) => {
// 先以一个固定的方法绑定,再在这个方法中执行 func,此时得到的 func 永远是最新的
console.log("validate.run");
deferred.current.resolve(funcRef.current(...args));
deferred.current = defer();
},
wait,
options
)
).current;
useLayoutEffect(() => {
funcRef.current = func;
});
return useCallback(
(...args: Args) => {
debouncedFunc(...args);
return deferred.current.promise;
},
[debouncedFunc]
);
}
react 如何使用防抖、节流函数
最新推荐文章于 2024-07-24 21:44:07 发布