在学习debounce方法时看到一篇很不错的文章,记录一下: dev.to/bwca/create…
代码
// debounce.ts
export function debounce<A = unknown, R = void>(
fn: (args: A) => R,
ms: number,
): [(args: A) => Promise<R>, () => void] {
let timer: NodeJS.Timeout;
const debounceFunc = (args: A): Promise<R> =>
new Promise((resolve) => {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
resolve(fn(args));
}, ms);
});
const clearDebounce = () => clearTimeout(timer);
return [debounceFunc, clearDebounce];
}
// useDebounce.ts
import { useEffect } from "react";
import { debounce } from "../utils/debounce";
export const useDebounce = <A = unknown, R = void>(
fn: (args: A) => R,
ms: number,
): ((args: A) => Promise<R>) => {
const [debounceFunc, clearDebounce] = debounce<A, R>(fn, ms);
useEffect(() => () => clearDebounce(), []);
return debounceFunc;
}
// 使用
const resize = useDebounce(() => {
...
}, 10);
重点
作者Volodymyr Yepishev的debounce方法返回了对timer的clear方法,原因在于等待函数执行的对象可能已经被销毁了,我们需要提供方法来停止函数的执行。 接下来作者将clear方法用自定义hook隐藏起来,当hook被销毁时,函数便不会再执行。