javascript如何实现防抖和节流_它们有何区别与用途【教程】
发布时间 - 2026-01-31 00:00:00 点击率:次防抖是“等最后一次”,节流是“固定间隔执行一次”;防抖适用于搜索框输入等需最终状态的场景,节流适用于滚动监听等需过程状态的场景。
防抖和节流不是“选一个用”,而是解决两类不同触发场景的问题:防抖适合「等用户彻底停手再执行」,节流适合「匀速稳定地响应高频事件」。
防抖(debounce)怎么写才不踩坑
核心是每次触发都清除上一次定时器,只保留最后一次的延时执行。常见错误是没处理 this 和参数透传,或忘记返回函数以便移除监听。
- 必须用
clearTimeout清除前序定时器,否则会累积执行 - 用
func.apply(context, args)保证原函数的this和参数正确传递 - 若需手动取消(比如组件卸载),得暴露
cancel方法 - 立即执行模式(leading edge)要单独判断,不能和 trailing 混在一起
简版实现:
function debounce(func, wait, immediate = false) {
let timeout;
return function(...args) {
const later = () => {
timeout = null;
if (!immediate) func.apply(this, args);
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(this, args);
};
}节流(throttle)为什么常用时间戳+定时器双机制
单靠 setTimeout 容易漏掉最后一次触发;只用时间戳又无法保证「至少执行一次」。双机制能兼顾首尾和均匀性。
- 时间戳方案:记录上次执行时间,当前时间减去它 ≥ wait 才执行,执行后更新时间戳
- 定时器方案:触发时若无 pending 定时器,则设一个,在结束时清空;但可能丢尾
- 推荐组合:用时间戳控制是否该执行,用定时器兜底保证最终执行(即「有头有尾」)
- 注意不要在滚动/拖拽中直接用
requestAnimationFrame替代节流——它不控制频率,只对齐帧率
可靠节流示例(时间戳 + 定时器):
function throttle(func, wait) {
let previous = 0;
let timeout = null;
return function(...args) {
const now = Date.now();
if (now - previous >= wait) {
func.apply(this, args);
previous = now;
} else {
clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(this, args);
previous = Date.now();
}, wait);
}
};
}input搜索、窗口缩放、按钮点击该用哪个
选型取决于「用户意图」和「业务语义」,不是看谁更“高级”。
-
input搜索建议:用防抖(debounce),等用户打完字再发请求,避免中间态浪费 API 调用 -
resize或scroll监听:优先节流(throttle),尤其涉及重排重绘时,需稳定节奏更新 UI - 防二次提交按钮:用防抖(
debounce),限制「连续点击」,但要注意首次点击必须立刻生效(immediate = true) - 鼠标拖拽位置上报:节流更稳妥,防抖会导致松手前位置丢失,体验断层
Lodas

debounce 和 throttle 哪些配置容易被忽略
它们默认行为和手写差异不小,尤其在边缘场景下表现不同。
-
leading: true+trailing: false组合会让防抖变成「首次立即执行,后续只清不延」,容易误以为失效 -
maxWait是节流的强制上限,即使一直触发,也会在maxWait后兜底执行——这点手写常遗漏 -
cancel()和flush()在异步清理或同步触发剩余任务时很关键,但多数人只记得调用主函数 - Lodash 版本 ≥ 4.0 后,
throttle默认启用leading和trailing,意味着首尾都会执行,和纯时间戳手写版行为不一致
真正难的不是写出一个能跑的版本,而是想清楚「这次用户动的是什么,系统该在什么时候、以什么节奏回应」——防抖和节流只是两个杠杆,支点在业务逻辑里。
# javascript
# java
# app
# edge
# ai
# 区别
# 重绘
# 为什么
# 事件
# this
# 异步
# input
# ui
# 防抖
# 双机
# 首次
# 适用于
# 的是
# 拖拽
# 有头有尾
# 更新时间
# 鼠标
# 什么时候
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?
北京网站制作的公司有哪些,北京白云观官方网站?
html5源代码发行怎么设置权限_访问权限控制方法与实践【指南】
如何在阿里云域名上完成建站全流程?
Laravel Seeder填充数据教程_Laravel模型工厂Factory使用
Zeus浏览器网页版官网入口 宙斯浏览器官网在线通道
如何快速查询网站的真实建站时间?
如何在Windows环境下新建FTP站点并设置权限?
香港服务器建站指南:外贸独立站搭建与跨境电商配置流程
Java类加载基本过程详细介绍
谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复
如何在建站之星绑定自定义域名?
JavaScript中的标签模板是什么_它如何扩展字符串功能
如何快速生成可下载的建站源码工具?
制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?
Laravel Telescope怎么调试_使用Laravel Telescope进行应用监控与调试
软银砸40亿美元收购DigitalBridge 强化AI资料中心布局
Gemini手机端怎么发图片_Gemini手机端发图方法【步骤】
如何在阿里云购买域名并搭建网站?
如何基于云服务器快速搭建个人网站?
Laravel如何处理JSON字段的查询和更新_Laravel JSON列操作与查询技巧
如何用美橙互联一键搭建多站合一网站?
Java解压缩zip - 解压缩多个文件或文件夹实例
Laravel如何实现数据库事务?(DB Facade示例)
html5如何实现懒加载图片_ intersectionobserver api用法【教程】
如何有效防御Web建站篡改攻击?
图册素材网站设计制作软件,图册的导出方式有几种?
如何注册花生壳免费域名并搭建个人网站?
Laravel任务队列怎么用_Laravel Queues异步处理任务提升应用性能
Laravel如何实现数据导出到CSV文件_Laravel原生流式输出大数据量CSV【方案】
教你用AI将一段旋律扩展成一首完整的曲子
Laravel如何创建自定义中间件?(Middleware代码示例)
,南京靠谱的征婚网站?
香港服务器网站卡顿?如何解决网络延迟与负载问题?
JavaScript如何实现路由_前端路由原理是什么
Laravel如何实现API速率限制?(Rate Limiting教程)
HTML5打空格有哪些误区_新手常犯的空格使用错误【技巧】
Python企业级消息系统教程_KafkaRabbitMQ高并发应用
iOS验证手机号的正则表达式
如何在阿里云ECS服务器部署织梦CMS网站?
青岛网站建设如何选择本地服务器?
JS实现鼠标移上去显示图片或微信二维码
大学网站设计制作软件有哪些,如何将网站制作成自己app?
如何在阿里云虚拟主机上快速搭建个人网站?
深圳网站制作平台,深圳市做网站好的公司有哪些?
深入理解Android中的xmlns:tools属性
HTML透明颜色代码怎么让图片透明_给img元素加透明色的技巧【方法】
怎样使用JSON进行数据交换_它有什么限制
高性能网站服务器部署指南:稳定运行与安全配置优化方案
Laravel如何实现本地化和多语言支持?(i18n教程)

