防抖(Debounce)与节流(Throttle)

一、核心概念对比

维度 防抖(Debounce) 节流(Throttle)
定义 事件触发后,等待固定时间再执行回调;若期间再次触发,则重新计时。 事件触发后,固定时间内只执行一次回调,后续触发被忽略。
目标 确保高频事件(如输入)的最终结果只触发一次。 确保高频事件(如滚动)按固定频率执行。
执行时机 最后一次触发后的等待时间结束时执行。 按固定时间间隔执行(如每秒一次)。
类比 电梯关门:有人进出时重新计时关门。 水龙头滴水:无论拧多快,水滴按固定频率落下。

二、代码实现

1. 防抖(Debounce)

javascript 复制代码
function debounce(fn, delay) {
  let timer = null;
  return function(...args) {
    clearTimeout(timer); // 清除之前的计时
    timer = setTimeout(() => {
      fn.apply(this, args); // 延迟执行
    }, delay);
  };
}

// 示例:输入框搜索建议
const searchInput = document.getElementById('search');
searchInput.addEventListener('input', debounce(function(e) {
  console.log('发起搜索请求:', e.target.value);
}, 500));

2. 节流(Throttle)

javascript 复制代码
function throttle(fn, interval) {
  let lastTime = 0;
  return function(...args) {
    const now = Date.now();
    if (now - lastTime >= interval) { // 判断是否达到时间间隔
      fn.apply(this, args);
      lastTime = now;
    }
  };
}

// 示例:滚动加载更多
window.addEventListener('scroll', throttle(function() {
  console.log('检查滚动位置,加载数据...');
}, 1000));

三、使用场景

场景 防抖(Debounce) 节流(Throttle)
输入框实时搜索 ✅ 用户停止输入后发起请求(如500ms无输入) ❌ 不适合(输入期间仍需响应)
窗口调整(resize) ✅ 调整结束后计算布局 ✅ 按固定频率更新布局(如每秒一次)
按钮防重复点击 ✅ 避免用户快速点击多次提交 ✅ 固定时间内只允许提交一次
滚动事件(scroll) ❌ 最后一次滚动后触发可能不符合预期 ✅ 滚动期间定期检查位置(如触底加载)
鼠标移动(mousemove) ❌ 需要连续响应时不适用 ✅ 限制高频更新(如拖拽元素时降低渲染频率)

四、高频面试问题

1. 如何手写防抖和节流?

  • 参考上述代码实现,注意闭包和apply绑定上下文。

2. 防抖和节流的本质区别是什么?

  • 防抖关注"最后一次触发后的结果",节流关注"固定间隔内的执行频率"。

3. 如何选择防抖或节流?

  • 防抖:适合结果导向型场景(如搜索建议、提交按钮)。
  • 节流:适合过程控制型场景(如滚动加载、实时定位)。

4. 防抖的立即执行版本如何实现?

  • 添加参数控制是否立即执行第一次触发:

    javascript 复制代码
    function debounce(fn, delay, immediate) {
      let timer = null;
      return function(...args) {
        if (immediate && !timer) {
          fn.apply(this, args); // 立即执行
        }
        clearTimeout(timer);
        timer = setTimeout(() => {
          if (!immediate) fn.apply(this, args);
          timer = null;
        }, delay);
      };
    }

五、常见误区

  • 过度依赖第三方库 :虽然Lodash的_.debounce和_.throttle功能完善,但面试需掌握原生实现。
  • 忽视this和参数绑定 :回调函数中需正确传递this和事件参数(如event)。
  • 时间间隔设置不合理:防抖的延迟过长会导致响应迟钝,节流的间隔过短会失去优化意义。

六、总结回答技巧

  • 一句话概括 :
    "防抖是延迟执行,确保连续触发只执行最后一次;节流是限频执行,确保连续触发按固定频率执行。"
  • 结合项目举例 :
    "在商品搜索页中,输入框用防抖减少请求次数;图片懒加载用节流控制滚动检查频率。"
  • 扩展思考 :
    "防抖和节流本质是闭包的应用,通过控制计时器和时间戳管理事件触发逻辑。"
相关推荐
Csvn1 小时前
并发模式:让渲染学会排队、插队和让路
前端
可乐鸡翅yeah_1 小时前
新手梳理:M3U8 线上问题,哪些是前端锅,哪些是后端锅
前端·ios·音视频·实时音视频·m3u8·音视频在线播放
Flynt1 小时前
Linear 用 1000 个 PR 换掉 styled-components,我写了 200 个按钮,把这笔账复现了一遍
前端·css·preact
JavaGuide2 小时前
NVIDIA 又开源了!这次给 AI Agent 加上权限管控
前端·后端
excel2 小时前
prisma 如何处理数据库竞态
前端·数据库·后端
莪_幻尘4 小时前
Skill 体检:30 个 Skill 全凭感觉?体检器先自曝了 8 个“假 0 分
前端·人工智能·llm
风骏时光牛马4 小时前
AI模型综合能力评测:性能、指令遵循与多场景实测对比
前端
Frag0ut4 小时前
Chrome与Chromium内核浏览器在Windows 11上的新特性全景解析
前端·chrome·windows·web安全·chromium·gemini ai·playready drm
此时不提桶,更待何时4 小时前
05-03-B-ClickHouse与OLAP面试与生产事故实战
clickhouse·面试·nosql
hiahiahia1234 小时前
实现完整 Tool Dispatcher
开发语言·前端