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

六、总结回答技巧

  • 一句话概括
    "防抖是延迟执行,确保连续触发只执行最后一次;节流是限频执行,确保连续触发按固定频率执行。"
  • 结合项目举例
    "在商品搜索页中,输入框用防抖减少请求次数;图片懒加载用节流控制滚动检查频率。"
  • 扩展思考
    "防抖和节流本质是闭包的应用,通过控制计时器和时间戳管理事件触发逻辑。"
相关推荐
Zhencode17 分钟前
Vue3 响应式依赖收集与更新之effect
前端·vue.js
x-cmd21 分钟前
[x-cmd] jsoup 1.22.1 版本发布,引入 re2j 引擎,让 HTML 解析更安全高效
前端·安全·html·x-cmd·jsoup
天下代码客38 分钟前
使用electronc框架调用dll动态链接库流程和避坑
前端·javascript·vue.js·electron·node.js
weixin199701080161 小时前
【性能提升300%】仿1688首页的Webpack优化全记录
前端·webpack·node.js
冰暮流星1 小时前
javascript之数组
java·前端·javascript
晚霞的不甘2 小时前
Flutter for OpenHarmony天气卡片应用:用枚举与动画打造沉浸式多城市天气浏览体验
前端·flutter·云原生·前端框架
xkxnq2 小时前
第五阶段:Vue3核心深度深挖(第74天)(Vue3计算属性进阶)
前端·javascript·vue.js
三小河2 小时前
Agent Skill与Rules的区别——以Cursor为例
前端·javascript·后端
Hilaku2 小时前
不要在简历上写精通 Vue3?来自面试官的真实劝退
前端·javascript·vue.js
三小河2 小时前
前端视角详解 Agent Skill
前端·javascript·后端