防抖(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)。
  • 时间间隔设置不合理:防抖的延迟过长会导致响应迟钝,节流的间隔过短会失去优化意义。

六、总结回答技巧

  • 一句话概括
    "防抖是延迟执行,确保连续触发只执行最后一次;节流是限频执行,确保连续触发按固定频率执行。"
  • 结合项目举例
    "在商品搜索页中,输入框用防抖减少请求次数;图片懒加载用节流控制滚动检查频率。"
  • 扩展思考
    "防抖和节流本质是闭包的应用,通过控制计时器和时间戳管理事件触发逻辑。"
相关推荐
YonyouHRSaaS3 小时前
AI视频面试系统定义、功能作用、品牌推荐、选择攻略
人工智能·面试·职场和发展·ai面试·视频面试·ai视频面试
平头哥技术团队3 小时前
Day 16 | 用 ul、ol、li 一个标签,把散资料收成有序的技能清单页
开发语言·前端·html·html5
代码青铜z4 小时前
不会写代码做小程序,模板开发和AI 编程靠谱吗?创业前先看这 5 件事
前端
小傅哥4 小时前
Java + DDD,1:1 复刻 Deepseek Harness 项目
前端·后端·ai编程
积硅步致千里4 小时前
Word 里的 .wmf 其实是 EMF:一次 metafile 转 PNG 排障
前端·后端
mayaairi4 小时前
Vue2 组件通讯(二):ref、自定义事件与provide/inject实战
前端·javascript·vue.js
开开心心就好4 小时前
PDF图片去水印软件,支持批量处理页面
前端·javascript·人工智能·智能手机·pdf·语音识别
爱敲代码的小杨.4 小时前
【Spring】Spring Web MVC
前端·spring·mvc
我的世界洛天依4 小时前
【胡桃讲编程】JS 入门第 1 课:Hello World,开启你的 JavaScript 编程之旅
javascript
小鱼爱吃草灬灬4 小时前
实时面试辅助排查清单:音频来源、问题输入与上下文
面试·职场和发展·音视频