实现一个 debounce 函数,让高频触发的函数只在停止触发一段时间后执行。
要求
- 支持传入任意参数和
this上下文。 - 每次调用都应重新计时。
- 返回一个可以取消待执行任务的函数。
参考实现
点击展开
type AnyFn = (...args: any[]) => any;
function debounce<T extends AnyFn>(fn: T, wait: number) {
let timer: ReturnType<typeof setTimeout> | undefined;
const debounced = function (
this: ThisParameterType<T>,
...args: Parameters<T>
) {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
timer = undefined;
fn.apply(this, args);
}, wait);
};
debounced.cancel = () => {
if (timer) clearTimeout(timer);
timer = undefined;
};
return debounced;
}
关键在于闭包保存定时器,并在真正执行前清理旧任务。cancel 让组件卸载或用户主动取消时不会留下异步副作用。
加载中...