CodeWalk

什么是防抖(Debounce)?请手写实现。

作者:孤独的心 · 2026-05-30 12:55

请解释防抖的原理、应用场景,并手写一个防抖函数(含 leading/trailing 选项)。

回答

孤独的心

防抖(Debounce):在事件被触发后 n 秒内如果再次触发则重新计时,只在最后一次触发后执行回调。

应用场景

  • 搜索框输入联想(输入停止后再请求)
  • 窗口 resize 完成后执行
  • 表单重复提交防止

实现

function debounce(fn, delay = 300, options = {}) {
  const { leading = false, trailing = true } = options;
  let timer = null;
  let isLeadingCalled = false;

  const debounced = function(...args) {
    const context = this;

    if (leading && !timer) {
      fn.apply(context, args);
      isLeadingCalled = true;
    } else {
      isLeadingCalled = false;
    }

    clearTimeout(timer);
    timer = setTimeout(() => {
      timer = null;
      if (trailing && !isLeadingCalled) {
        fn.apply(context, args);
      }
    }, delay);
  };

  debounced.cancel = () => {
    clearTimeout(timer);
    timer = null;
  };

  debounced.flush = function(...args) {
    clearTimeout(timer);
    timer = null;
    fn.apply(this, args);
  };

  return debounced;
}

leading 和 trailing 解释

  • leading: true:在第一次触发时立即执行(如:立即发送请求)
  • trailing: true(默认):最后一次触发后再执行
  • 同时为 true 时:首次触发执行,等待期间连续触发则只执行最后一次(如:lodash debounce 默认行为)
  • cancel():取消防抖
  • flush():立即执行