节流 VS 防抖 相关知识点与面试题

文章目录

  • [防抖 (Debounce) 与 节流 (Throttle)](#防抖 (Debounce) 与 节流 (Throttle))
    • [一、 核心定义与区别](#一、 核心定义与区别)
      • [1. 防抖 (Debounce)](#1. 防抖 (Debounce))
      • [2. 节流 (Throttle)](#2. 节流 (Throttle))
      • [3. 对比总结](#3. 对比总结)
    • [二、 使用场景](#二、 使用场景)
      • [🛠 防抖 (Debounce) 的使用场景](#🛠 防抖 (Debounce) 的使用场景)
      • [⚙️ 节流 (Throttle) 的使用场景](#⚙️ 节流 (Throttle) 的使用场景)
    • [三、 使用它们的好处](#三、 使用它们的好处)
    • [四、 常见面试题](#四、 常见面试题)
      • [A. 手写实现一个基础版防抖](#A. 手写实现一个基础版防抖)
      • [B. 手写实现一个基础版节流(定时器版)](#B. 手写实现一个基础版节流(定时器版))

防抖 (Debounce) 与 节流 (Throttle)

在前端开发中,防抖节流是优化高频率执行代码(如滚动、输入、调整窗口大小)的核心手段。


一、 核心定义与区别

1. 防抖 (Debounce)

  • 定义 :在事件被触发 n n n 秒后再执行回调,如果在这 n n n 秒内事件又被触发,则重新计时
  • 形象比喻:就像电脑的**"待机睡眠"**。你最后一次操作鼠标后,电脑开始倒计时 10 分钟;如果你在第 9 分钟动了一下,倒计时立刻重置,重新等 10 分钟。

2. 节流 (Throttle)

  • 定义 :规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发了多次函数,只有一次生效。
  • 形象比喻 :就像**"红绿灯""水龙头滴水"**。无论路口有多少辆车想冲过去,绿灯亮起的时间间隔是固定的;或者水龙头每隔 3 秒滴一滴水,中间你如何拧开关都没用。

3. 对比总结

特性 防抖 (Debounce) 节流 (Throttle)
核心逻辑 重置计时器,只执行最后一次 锁定执行周期,每隔一段时间执行一次
关注点 关注"空闲时间",等到彻底安静后再执行 关注"执行频率",在持续触发中按节奏执行
执行次数 无论触发多少次,最终可能只执行一次 持续触发时,会按固定频率执行多次

二、 使用场景

🛠 防抖 (Debounce) 的使用场景

  • 搜索框输入 (Input):用户不停输入字符时,没必要每打一个字就发一次 AJAX 请求,等用户停下 500ms 后再发送。
  • 窗口大小调整 (Resize):用户拉伸窗口时,等拉伸结束再重新计算布局或 ECharts 图表自适应。
  • 表单提交按钮:防止用户因为手抖或网络延迟快速多次点击,导致重复提交订单或数据。

⚙️ 节流 (Throttle) 的使用场景

  • 鼠标移动 (Mousemove):在实现拖拽效果时,每秒计算几十次位置足够了,不需要每微秒都计算。
  • 滚动监听 (Scroll):监听用户滚动到底部加载更多(Infinite Scroll),每 200ms 检查一次距离即可。
  • 游戏技能释放:无论玩家按键多快,技能的冷却时间(CD)是固定的,强制限制触发频率。

三、 使用它们的好处

  1. 性能优化:减少 CPU 和内存的占用,避免高频操作导致页面卡顿、掉帧。
  2. 节省资源:显著减少向后端发送 API 请求的次数,减轻服务器压力和带宽消耗。
  3. 提升用户体验:避免因为无效的重复计算或异步请求冲突导致页面响应混乱。

四、 常见面试题

A. 手写实现一个基础版防抖

javascript 复制代码
function debounce(fn, delay) {
  let timer = null;
  return function(...args) {
    if (timer) clearTimeout(timer); // 只要进来就清空之前的计时
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  };
}

B. 手写实现一个基础版节流(定时器版)

javascript 复制代码
function throttle(fn, delay) {
  let timer = null;
  return function(...args) {
    if (!timer) { // 如果没锁,就设置一个定时器
      timer = setTimeout(() => {
        fn.apply(this, args);
        timer = null; // 执行完后解锁
      }, delay);
    }
  };
}
相关推荐
We་ct2 小时前
AI辅助开发术语体系深度剖析
开发语言·前端·人工智能·ai·ai编程
去伪存真2 小时前
Superpowers 从“调教提示词”转向“构建工程规范”
前端·agent
发现一只大呆瓜2 小时前
深度起底 Vite:从打包流程到插件钩子执行时序的全链路解析
前端·vite
jserTang2 小时前
Claude Code 源码深度解析 - 前言
前端·javascript·后端
hehelm2 小时前
vector模拟实现
前端·javascript·算法
|晴 天|2 小时前
[特殊字符]️ Vue 3项目架构设计:从2200行单文件到24个组件
前端·javascript·vue.js
FrontAI2 小时前
深入浅出 LangChain —— 第三章:模型抽象层
前端·人工智能·typescript·langchain·ai agent
givemeacar2 小时前
spring-boot-starter和spring-boot-starter-web的关联
前端
leoZ2313 小时前
金仓老旧项目改造-10
开发语言·前端·人工智能·python·金仓