手写 debounce

实现一个 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 让组件卸载或用户主动取消时不会留下异步副作用。

评论

加载中...