当前位置: 首页 > news >正文

JavaScript:防抖与节流

文章目录

  • 防抖(Debounce)
  • 节流 (Throttle)

在JavaScript中,防抖(debounce)和节流(throttle)是两种优化函数调用频率的策略,它们主要用于限制频繁触发的事件回调函数执行次数,以防止过多不必要的计算和网络请求,从而提高性能并减少资源消耗。

防抖(Debounce)

防抖的核心思想是:当连续快速触发同一事件时,只有在最后一次触发后的一段时间内没有再次触发该事件,才会执行对应的处理函数。例如,在输入框搜索场景下,用户在短时间内连续输入字符,通过防抖可以确保在用户停止输入一段时间后再发送搜索请求

实现原理通常是设置一个定时器,每次事件触发时都会清除上一次的定时器并重新设置一个新的定时器。如果在指定的时间间隔内又有新的事件触发,则会继续取消当前定时器并重置。直到最后一定时间间隔内无新事件触发时,之前设置的最后一个定时器到期后才真正执行回调函数。

//func 是需要被防抖处理的函数,wait 是等待时间(单位为毫秒)
function debounce(func, wait) {//在外部作用域中定义一个变量 timeoutId 用于存储定时器ID,以便后续取消已设置的定时器。let timeoutId;return function (...args) {//清除之前已经设定好的定时器if (timeoutId) clearTimeout(timeoutId);//重新设置一个新的定时器,延迟指定的 wait 毫秒后执行回timeoutId = setTimeout(() => {//调用原始的 func 函数func.apply(this, args);}, wait);};
}// 示例:在窗口调整大小时触发防抖函数
window.addEventListener('resize', debounce(function handleResize() {console.log('Window resized');
}, 300)); // 只有在用户停止调整窗口大小300毫秒后才会打印日志

节流 (Throttle)

节流则是另一种限制频率的方式,它允许事件在固定时间段内只执行一次。即使事件被频繁触发,但在每个时间段内只会执行一次操作。这样可以保证无论事件触发多么频繁,函数至少每过一段时间就会执行一次。

例如,在窗口滚动事件监听中,使用节流可以确保在用户滚动过程中每隔一定时间(比如每秒)更新一次视图位置,而不是在滚动期间不断刷新,从而避免过度渲染导致的性能问题。

实现节流的方法通常包括设置定时器,并在每一次事件触发时检查是否需要重新开始计时或直接执行回调函数。

function throttle(func, wait) {let lastExecutionTime = 0;//存储最后一次执行该函数的时间戳let timerId;//存储定时器ID以便在必要时取消已设置的定时器return function (...args) {const now = Date.now();//如果当前时间与上次执行时间差大于等于等待时间 wait,则直接执行原函数if (now - lastExecutionTime >= wait) {func.apply(this, args);lastExecutionTime = now;} else if (!timerId) {//创建一个新的定时器,延迟时间为wait - (now - lastExecutionTime)即wait时间内剩余时间timerId = setTimeout(() => {//执行原函数,并在执行完成后清空 timerId,同时将当前时间更新到 lastExecutionTimefunc.apply(this, args);timerId = null;lastExecutionTime = Date.now();}, wait - (now - lastExecutionTime));}};
}// 示例:在窗口滚动时触发节流函数
window.addEventListener('scroll', throttle(function handleScroll() {console.log('Window scrolled');
}, 500)); // 在滚动期间每过至少500毫秒会打印一次日志,即使滚动事件触发更频繁

总结来说,防抖更关注于限制最后一次操作之后的重复操作,而节流则关注于控制函数在一个时间段内的执行次数。

注:
.apply()方法用于调用一个函数,并允许传入一个数组(或类数组对象)作为参数列表,同时也可以指定函数执行时的上下文(this值)

function add(a, b) {return a + b;
}let numbers = [3, 5];
console.log(add.apply(null, numbers)); // 输出:8// 或者使用数组字面量作为参数
console.log(add.apply(null, [3, 5])); // 输出:8// 使用上下文
let obj = { value: 10 };
let multiply = function(a) {return this.value * a;
};
console.log(multiply.apply(obj, [2])); // 输出:20

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • C# 中的回调函数
  • 【笔记】【算法设计与分析 - 北航童咏昕教授】绪论
  • v-rep插件
  • AWS Elastic Beanstalk通过单实例配置https
  • 【STM32 CubeMX】adxl345加速度传感器
  • 面试经典150题 -- 链表 (总结)
  • EasyCaptcha,开源图形验证码新标杆!
  • 软件测试进阶自动化测试流程
  • 人工智能_普通服务器CPU_安装清华开源人工智能AI大模型ChatGlm-6B_001---人工智能工作笔记0096
  • Write operation failed: computed value is readonly问题解决
  • 【小沐学GIS】基于C++QT绘制三维数字地球Earth(OpenGL)
  • VMware还原Windows11 ghost镜像
  • 【leetcode】贪心算法介绍
  • Linux系统安全——iptables相关总结
  • LeetCode_20_简单_有效的括号
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • 2017 年终总结 —— 在路上
  • Codepen 每日精选(2018-3-25)
  • CSS3 聊天气泡框以及 inherit、currentColor 关键字
  • E-HPC支持多队列管理和自动伸缩
  • Hibernate最全面试题
  • Java 多线程编程之:notify 和 wait 用法
  • js操作时间(持续更新)
  • Lsb图片隐写
  • Map集合、散列表、红黑树介绍
  • Mybatis初体验
  • Shadow DOM 内部构造及如何构建独立组件
  • spring + angular 实现导出excel
  • Terraform入门 - 1. 安装Terraform
  • vue-cli3搭建项目
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 数组大概知多少
  • 数组的操作
  • Java数据解析之JSON
  • 我们雇佣了一只大猴子...
  • ​人工智能之父图灵诞辰纪念日,一起来看最受读者欢迎的AI技术好书
  • ​如何使用ArcGIS Pro制作渐变河流效果
  • ## 基础知识
  • #include<初见C语言之指针(5)>
  • #mysql 8.0 踩坑日记
  • $forceUpdate()函数
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (四十一)大数据实战——spark的yarn模式生产环境部署
  • (转)c++ std::pair 与 std::make
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • (轉)JSON.stringify 语法实例讲解
  • .FileZilla的使用和主动模式被动模式介绍
  • .JPG图片,各种压缩率下的文件尺寸
  • .NET C#版本和.NET版本以及VS版本的对应关系
  • .net CHARTING图表控件下载地址
  • .NET Conf 2023 回顾 – 庆祝社区、创新和 .NET 8 的发布
  • .net core 依赖注入的基本用发
  • .NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)