防抖 Debouncing 深度解析:一个定时器如何吞掉 20 次调用

发布时间:2026/11/4 1:13:32

防抖 Debouncing 深度解析:一个定时器如何吞掉 20 次调用 防抖 Debouncing 深度解析一个定时器如何吞掉 20 次调用【免费下载链接】30-seconds-of-interviewsA curated collection of common interview questions to help you prepare for your next interview.项目地址: https://gitcode.com/gh_mirrors/30/30-seconds-of-interviews搜索框每按一个键就发一次请求、滚动监听每秒触发 20 多次重活还在傻跑——这是前端高频事件的常见事故现场。防抖Debouncing就是为此而生的事件不停代码不跑事件一停才执行一次。开源面试题库 30-seconds-of-interviews 用一份 Markdown 题目文件就把这套机制讲完了下面从事故现场到仓库管线完整走一遍。先花 30 秒拿住核心防抖的本质把时间窗口内的多次连续调用合并成窗口结束后的一次执行裸 DOM 事件监听器每秒可以轻松触发 20 次防抖版只在延迟期满后调用一次全部实现就两个 APIclearTimeoutsetTimeout外加一个用闭包Closure保存的定时器句柄判断标准事件还在密集触发定时器永远到不了期事件停了最后一个定时器走完目标函数执行恰好一次经典落点搜索输入停键后才发 API 请求、scroll/resize处理降频。机制对读定时器被反复清零的游戏想象一个带自动闭门器的门。你每推它一次闭门器就重新归位、重新计时只有当你有一段时间不推门它才唰地关上。防抖就是给函数装了这么个闭门器第 1 次调用启动一个delay毫秒的定时器delay内又来第 2 次调用先clearTimeout掐掉上一个再重新计时事件持续到来定时器被反复清零目标函数一次都没跑事件停止最后一个定时器独自走完——函数执行恰好一次且拿到的是最后一次调用的参数。关键在于定时器句柄存在哪它必须在返回函数的外层作用域里闭包下一次调用才拿得到上一次的句柄去清除。句柄若声明在内层每次调用都是一个新值clearTimeout永远清不到东西合并能力直接失效。动手实现12 行可跑的防抖下面是仓库题目给出的标准实现原样引用注意原文addEventListere为拼写错误应为addEventListenerconst debounce (func, delay) { let debounceTimer; // 闭包保存定时器句柄 return function() { const context this; // 捕获调用时的 this const args arguments; // 捕获全部实参 clearTimeout(debounceTimer); // 掐掉上一次未到的定时器 debounceTimer setTimeout(() func.apply(context, args), delay); } } window.addEventListener(scroll, debounce(function() { // Do stuff, this function will be called after a delay of 1 second }, 1000));逐行说人话let debounceTimer声明在返回函数之外靠闭包跨调用存活是重置能力的前提clearTimeout必须在setTimeout之前执行顺序反了就白搭context/args加上func.apply包装层原样透传调用现场不改写目标函数的语义用法上debounce(fn, 1000)返回的是新的包装函数挂到scroll上的是它1 秒后用户停止滚动真实回调才执行一次。工程账本优化前 vs 优化后以输入 react 这 5 个字符每键发一次搜索请求为例维度不加防抖300ms 防抖网络请求次数5 次1 次用户体感连续刷新结果旧响应可能覆盖新结果停顿后出一次结果稳定主线程负担每次按键都渲染仅末态渲染一次再对照滚动场景题目里明确裸监听器每秒可触发 20 次防抖后一段连续滚动只结算一次。两个场景共同指向同一条原则——以末态为准的事末次搜索词、末次视口尺寸交给防抖最划算。追问时间面试官真正想听的部分追问 1防抖 vs 节流边界在哪对比项防抖debounce节流throttle执行时机调用停止后延迟执行一次固定间隔内至多一次控制对象窗口内的调用次数执行的频率上限典型场景搜索、resize 后重排拖拽、滚动进度、游戏循环末态保证保证用最后一次参数不保证可能丢末态记忆锚点要末态选防抖要保底频率选节流。追问 2this和参数为什么单独接住外层return function()必须是普通函数而非箭头函数——事件监听器里this是动态的窗口或绑定元素箭头函数会把它锁死成定义时的作用域arguments则原样接住所有实参最后经func.apply一次性透传。追问 3首次调用能立即执行吗能这就是 leading edge 模式首次调用直接执行之后进入冷却期忽略后续调用delay结束才解锁。但仓库给出的标准实现是 trailing末次执行面试先答这个再主动补一句需要首触立即执行时可用 leading 版层次就出来了。项目视角这道题在仓库里走了哪条链路questions/debouncing.md——内容源。含#### Answer、#### Good to hear等固定小节格式约定见 question-template.md另有!-- tags: --、!-- expertise: --隐藏注释承载标签与难度scripts/util.js——解析工具层。readQuestions()按字母序读取整个questions/目录getSection()按标题切块getCodeBlocks()抽取代码块scripts/extract.js——管线核心。把每题的 question / answer / goodToHear / 难度 / 代码块组装成对象写入data/questions.json对应package.json里的extractor: node ./scripts/extract.jsdata/questions.json——数据文件前端唯一数据源由 website/js/state.js 直接 import 进 Hyperapp 状态website/js/components/——展示层Filter.js管标签过滤Questions.js负责按难度排序渲染列表Question.js展开单题Markdown.js用 marked 渲染答案、Prism 高亮代码。一条冷知识可以加分当前提交的data/questions.json只有 103 道题而questions/目录已有 109 个 md 文件debouncing.md还没进数据——这道题是在数据快照之后加入的重跑一次extractor脚本它就会出现在网站上。自测卡片防抖一次触发里clearTimeout和setTimeout各执行几次持续滚动 3 秒后停止delay1000ms回调执行几次外层返回箭头函数会丢掉什么需要保证每 100ms 至少执行一次的场景该选防抖还是节流关键词收束防抖Debouncing、clearTimeoutsetTimeout、闭包状态、末态合并、防抖和节流的区别debounce vs throttle。【免费下载链接】30-seconds-of-interviewsA curated collection of common interview questions to help you prepare for your next interview.项目地址: https://gitcode.com/gh_mirrors/30/30-seconds-of-interviews创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/11/4 1:08:32

嵌入式开发实战复盘:ARM、FPGA与边缘计算落地经验分享

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/4 2:58:45

实例依赖性标签噪声在部分标签学习中的建模与优化

1. 论文核心问题解析这篇论文探讨的是部分标签学习(Partial Label Learning, PLL)中一个长期被忽视的关键问题——实例依赖性(Instance-Dependent)的标签噪声。传统PLL方法通常假设标签噪声是随机均匀分布的,但现实场景…

2026/11/4 2:58:45

TPOT指标:优化LLM推理性能的关键

1. 为什么TPOT比平均延迟更重要在评估大型语言模型(LLM)推理性能时,大多数开发者第一反应都是看平均延迟(Average Latency)这个指标。但真正经历过生产环境考验的工程师都知道,单纯依赖平均数会掩盖很多关键…

2026/11/4 2:58:45

Java在线问诊系统开发:技术架构与医疗信息化实践

1. 项目概述这个基于Java语言的在线问诊系统,本质上是一个B/S架构的医疗健康服务平台。它把传统的线下就医流程数字化,让患者足不出户就能完成从咨询到取药的全过程。我在医疗信息化领域工作多年,见证过太多"排队三小时,看病…

2026/11/4 2:58:45

Oracle 11g升级19C:DBUA与RMAN恢复实战指南

简介:《Oracle 11g 到 19C 数据库升级详尽指导手册》面向具备一定运维能力的数据库管理员,聚焦利用 DBUA 将 11g 单机库安全迁移至 19C 的维护场景。内容覆盖前期备份与恢复、升级路线与环境核对、图形及静默升级方式、必要参数调整,以及检查…

2026/11/4 2:58:45

双指针法实现数组原地元素删除

1. 题目解析与需求拆解这道题目要求我们原地移除数组中所有等于给定值的元素,并返回新数组的长度。看似简单,但其中蕴含着几个关键考察点:原地操作:不能使用额外数组空间,必须在原数组上修改元素顺序:剩余元…

2026/11/4 2:53:45

鸿蒙6.0存储技术:AppStorageV2与PersistenceV2深度解析

1. 鸿蒙6.0存储技术演进背景在鸿蒙6.0版本中,应用数据存储能力迎来了重要升级。AppStorageV2和PersistenceV2作为新一代存储解决方案,解决了开发者长期面临的几个痛点问题:跨设备数据同步效率低、大数据量存储性能瓶颈、以及复杂数据结构的序…

2026/11/3 7:47:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/3 14:24:53

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/4 0:03:20

AI辅助技术栈评估:提升研发决策效率60%

1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年…

2026/11/4 0:03:20

从生成Token到直接决策:Jev如何重塑AI Agent工程实践

1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你…

2026/11/4 0:03:20

32G统一内存跑大模型:内存账、TPS实测与端云分流

想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统…

2026/11/3 7:47:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/3 14:24:53

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑