Debounce方法Typescript + React实现

1,101 阅读1分钟

在学习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被销毁时,函数便不会再执行。

链接

dev.to/bwca/create…