30-seconds-of-interviews 里的 debouncing为什么你的搜索框还在疯狂发请求【免费下载链接】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页面卡不是网络慢是你的代码在每次键入时都老老实实发了一次请求。用户敲完 react 这五个字母Network 面板里已经躺着五个重复的 /search 调用换成 scroll 事件裸监听器每秒轻松触发二十多次主线程直接被灌满。这是 30-seconds-of-interviews 里 debouncing防抖这道题反复出现的背景——高频事件不该每次都干活。先把最直觉的写法摆出来看看它为什么救不了场// 最直觉的防抖包装时就把执行延迟掉 const debounce (func, delay) setTimeout(func, delay); window.addEventListener(scroll, debounce(() { // 更新滚动条相关 UI }, 1000));这段代码的定时器在 addEventListener 那一行就启动了页面加载完一秒后回调执行一次此后的滚动全部被忽略。事件来了既没有重置计时函数也没等到用户停手才动手——它连防的对象都没找对更糟的是 func 里的参数与上下文在这个版本里同样没有着落。迭代两版修出一个能跑的 debounce 实现 要合并且只在最后执行一次得让定时器跟着每次事件走再把 this 和参数还给原函数。两步走迭代一让定时器跟着事件走先给函数套上闭包里的计时器每次调用先掐掉旧的再立新的const debounce (func, delay) { let timer; return function () { clearTimeout(timer); timer setTimeout(func, delay); }; };到这里停止触发后只执行一次的行为已经对了。但setTimeout(func, delay)是裸调用原函数拿不到调用时的this比如事件元素也接不到arguments。只要被包函数依赖这两样——哪怕只是想读一下 event 参数——就立刻翻车。迭代二把 this 和参数透传回去调用时把上下文和参数存下来到期时再 apply 回去const debounce (func, delay) { let timer; return function () { const context this; const args arguments; clearTimeout(timer); timer setTimeout(() func.apply(context, args), delay); }; }; window.addEventListener(scroll, debounce(function () { // 用户停止滚动 1 秒后只执行这一次 console.log(scroll settled on, this); }, 1000));这里有个容易忽略的点外层刻意写成普通函数才能动态捕获调用时的 this 与 arguments内层 setTimeout 回调却用箭头函数让 func.apply(context, args) 依赖的闭包变量不被覆盖。这个内外有别是面试官最爱抠的细节。拿搜索输入这条流程压一压行为对不对走一遍时间线最清楚。设防抖延迟 300mst0 敲下 r立一个计时器t100ms 敲 re掐掉旧的立新的t900ms 敲完 act——只要持续输入计时器永远到不了期。用户在 t900ms 停手t1200ms 最后一个计时器到期请求发出去全程只有 1 次而不是 5 次。反过来如果用户在 t600ms 处短暂停顿了 400ms那一次停顿就会兑现一次请求之后继续输入又重新立计时器——每次停顿对应一次执行这正是防抖的语义。const searchInput document.querySelector(#search); // 把发请求包成 300ms 防抖输入停顿后才真正请求 const fetchResults debounce(function (query) { fetch(/api/search?q${encodeURIComponent(query)}) .then((res) res.json()) .then(renderResults); }, 300); searchInput.addEventListener(input, (event) { fetchResults(event.target.value); });这里 fetchResults 拿到的 event.target.value 正是靠上一版的 args 透传过去的——透传没修好的话query 就是 undefined。顺带一提只发一次请求还避免了旧响应盖掉新结果带来的竞态。给 debounce 加 cancel 和 leading再和节流比一比 ⚠️面试官大概率会接着问真到生产环境这版还差什么差两件事——主动取消的能力以及首次立即执行的 leading 模式const createDebounced (func, delay, { immediate false } {}) { let timer; const debounced function (...args) { // 冷却期内timer 存在leading 模式直接忽略本次 const callNow immediate !timer; clearTimeout(timer); timer setTimeout(() { timer null; if (!immediate) func.apply(this, args); }, delay); if (callNow) func.apply(this, args); }; // 组件卸载等场景主动取消挂起的调用 debounced.cancel () clearTimeout(timer); return debounced; };immediate 为 true 时首次调用立刻执行、随后进入冷却期直到 timer 清空适合首次点击立刻响应的点赞类交互cancel 则负责在组件卸载前掐掉还没到期的那次执行避免回调去操作已经不存在的 DOM。这里有个容易踩的坑把一个已经防抖过的函数再传进 debounce 包一层两个定时器叠加延迟语义直接错乱排查起来非常痛苦——防抖函数应当只包一次。和节流的关系用这张表说清维度debounce 防抖throttle 节流执行时机事件停止触发、延迟期满后才执行一次固定间隔内最多执行一次典型场景搜索输入、resize 后重算布局滚动加载、拖拽、轮询本质合并窗口内的多次调用限制执行频率的上限最后一次调用必然兑现trailing视实现而定从 Markdown 到页面这道题的数据流题目本身就是仓库里的一份 Markdown走完一条固定链路才出现在页面上。questions/debouncing.md 存放这道题的问法、标准答案和 scroll 示例答案与补充话术分别写在#### Answer和#### Good to hear两个小节里scripts/extract.js 负责把 questions/ 下的全部 Markdown 转成 JSON按小节切内容的活由 scripts/util.js 里的 getSection 完成输出的 data/questions.json 再被前端消费website/js/components/Filter.js 渲染出按标签过滤、排序的控件让你在题库页按 JavaScript 这类标签筛出这道题。整条链路一句话Markdown 题目 → extract.js 解析 → questions.json → 前端组件渲染。面试前先回答自己这五个问题与其背实现不如先逼自己答对这几个面试官问为什么外层用普通函数、内层用箭头函数你能一句话说清吗如果 delay 传 0防抖还算防抖吗把已经防抖过的函数再包一层回调最终会延迟多久、为什么React 类组件里 cancel 应该挂在哪个生命周期忘了会怎样用户连续输入三十秒不停顿中间发过请求吗能把这五个问题顺下去这道题就扛得住追问了。【免费下载链接】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),仅供参考
企业数字化 ERP 产品动态
相关推荐
Hermes Agent与身份管理系统集成:用户认证与权限控制 Hermes Agent与身份管理系统集成:用户认证与权限控制
在当今数字化时代,身份管理和权限控制是任何系统安全的核心环节。Hermes Agent作为一款功能强大的AI代理框架,提供了灵活的身份管理集成方案,帮助开发者轻松实现安全可靠的用… · 2026/11/4 15:33:34
5个关键问题解答:如何用Hermes Agent搭建智能数据分析与可视化平台? 5个关键问题解答:如何用Hermes Agent搭建智能数据分析与可视化平台?
在数据驱动的时代,企业如何快速构建高效的数据分析解决方案?想象一下,您是否曾面临数据孤岛、分析工具分散、可视化效果不佳的困扰?今天… · 2026/11/4 15:33:34
Hermes Agent:物联网设备固件更新的安全自动化解决方案 Hermes Agent:物联网设备固件更新的安全自动化解决方案
在物联网(IoT)快速发展的今天,设备固件更新管理面临着安全与效率的双重挑战。Hermes Agent作为一款强大的自动化工具,通过集成安全防护机制与自动化工作流&… · 2026/11/4 15:33:34
技术博客从零搭建:静态站点、自动部署与SEO收录实战 先说一个我观察到的现象:大部分人的技术博客死在第 7 天,而不是死在第 700 天。搭建本身只花了两个晚上,第三次更新之后就再也没有打开过那个仓库。原因通常不是懒,而是搭建阶段做了一堆当时觉得"很专业"、事后全变成阻… · 2026/11/4 17:52:57
SQL Server 2012 32位安装教程:配置检查与避坑清单 简介:这份 PDF 图解教程面向准备在 Windows 7 SP1 32 位环境部署 SQL Server 2012 的初学者与运维人员,重点介绍安装前环境确认、安装包选择、系统配置检查、实例与服务器配置、身份验证模式以及数据库引擎设置等关键环节,并通过分步截图和界… · 2026/11/4 17:52:57
Vue 3 Teleport组件:DOM传送门实战指南 1. Vue Teleport 是什么?Vue Teleport 是 Vue 3 内置的一个组件功能,它允许你将模板中的一部分内容"传送"到 DOM 树的其他位置。想象一下,就像科幻电影里的传送门一样,你可以把组件的一部分"传送"到任何你想放… · 2026/11/4 17:52:57
32位Win7安装SQL Server 2012:介质、实例与sa配置避坑 简介:SQL Server 2012 安装图解教程以单份 PDF 形式呈现,面向初次接触微软数据库、需在 Windows 7 SP1 32 位等环境中完成部署的开发者与运维学习者,帮助其建立安装流程的整体认识,减少环境准备阶段的盲目尝试。压缩包内仅含 1 个… · 2026/11/4 17:52:57
Windows下GCC工具链怎么选:MinGW、TDM-GCC与MSYS2 去年帮一个做桌面工具的小团队收拾构建环境,代码在 Linux 上一路绿灯,拿到 Windows 上就全是毛病:链接阶段报undefined reference to __imp_...,编译出来的程序双击闪退提示找不到libstdc-6.dll,最离谱的是一个std::th… · 2026/11/4 17:52:57
网络安全行业趋势与零信任架构实践指南 1. 行业现状与挑战网络安全行业近年来呈现爆发式增长态势,全球市场规模预计将在2026年突破3000亿美元。这个数字背后反映的是数字化转型浪潮下,企业对安全防护的刚性需求。但与此同时,行业也面临着前所未有的挑战。从技术层面来看,… · 2026/11/4 17:51:56
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* 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 3:16:49
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* 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 6:59:29
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* 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 7:02:38
AI辅助技术栈评估:提升研发决策效率60% 1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年… · 2026/11/4 0:00:17
从生成Token到直接决策:Jev如何重塑AI Agent工程实践 1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你… · 2026/11/4 0:00:17
32G统一内存跑大模型:内存账、TPS实测与端云分流 想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统… · 2026/11/4 0:00:17
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* 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 3:16:49
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* 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 6:59:29
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* 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 7:02:38