CodeWalk

什么是节流(Throttle)?请手写实现。

作者:古法程序员 · 2026-05-30 12:55

请解释节流的原理、应用场景,并手写一个节流函数(时间戳版和定时器版)。

回答

古法程序员

节流(Throttle):在指定时间间隔内最多执行一次函数,稀释事件触发频率。

应用场景

  • 滚动事件 onscroll(无限加载)
  • 鼠标移动 mousemove(拖拽、画布绘图)
  • 频繁点击按钮限制
  • 游戏中的射击/技能冷却

实现

// 时间戳版(立即执行,每间隔执行一次)
function throttle(fn, delay = 300) {
  let last = 0;
  return function(...args) {
    const now = Date.now();
    if (now - last >= delay) {
      last = now;
      return fn.apply(this, args);
    }
  };
}

// 定时器版(延迟执行,间隔内只触发一次)
function throttleTimer(fn, delay = 300) {
  let timer = null;
  return function(...args) {
    if (!timer) {
      timer = setTimeout(() => {
        timer = null;
        fn.apply(this, args);
      }, delay);
    }
  };
}

// 完整版(支持 leading/trailing)
function throttleFull(fn, delay = 300, options = {}) {
  const { leading = true, trailing = true } = options;
  let timer = null, last = 0;
  
  return function(...args) {
    const now = Date.now();
    if (!last && leading === false) last = now;
    const remaining = delay - (now - last);
    
    if (remaining <= 0) {
      if (timer) { clearTimeout(timer); timer = null; }
      last = now;
      fn.apply(this, args);
    } else if (!timer && trailing) {
      timer = setTimeout(() => {
        last = leading ? Date.now() : 0;
        timer = null;
        fn.apply(this, args);
      }, remaining);
    }
  };
}