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

手写节流和防抖

一、什么是防抖

定义: 用于限制某个函数在短时间内被频繁调用的情况

特点:

  • 延迟执行:防抖会延迟执行目标函数,直到一定的空闲时间过去后才执行,如果在这段时间内再次触发,则会重新计时。

  • 合并触发:多次连续触发的事件会被合并为一次触发,只有在最后一次触发后的空闲时间内没有再次触发才会执行目标函数。

应用:

  • 输入框实时搜索:在用户输入搜索关键词时,使用防抖可以避免在用户输入过程中频繁触发搜索请求,提高搜索性能和用户体验。

  • 按钮点击事件:在防止用户重复点击按钮后多次触发事件时,可以利用防抖来控制按钮的点击事件,确保只有在用户停止点击后才执行操作。

  • 窗口大小调整:当用户调整窗口大小时,很多页面布局或响应式设计需要重新计算和调整,使用防抖可以确保在用户停止调整窗口大小后再执行相关操作,避免频繁重绘页面。

  • 滚动事件:处理页面滚动事件时,可以利用防抖减少滚动过程中触发的频繁计算,只有在用户滚动停止后才执行相关处理。

优点:

  • 性能优化:防抖可以减少不必要的函数执行次数,降低性能消耗,提高页面性能和响应速度。

  • 用户体验:在一些交互场景下,使用防抖可以有效控制事件触发频率,提升用户体验和界面流畅度。

  • 数据请求控制:在需要向后端发起请求的场景中,防抖可以避免频繁请求数据,减少网络流量和服务器压力。

总的来说,防抖是一种常用的前端技术,通过控制事件触发频率,可以优化性能、提升用户体验,并有效应用于多种交互场景中。

案例:
逻辑梳理:

  • 在这个示例中,debounce函数接受两个参数:需要防抖的函数 func 和延迟时间 delay。返回一个新的函数,用于包裹原始函数 func,并在延迟时间内只允许触发一次执行。

  • 通过调用 debounce(doSomething, 1000) 创建一个防抖函数 debouncedFunction,然后可以多次调用 debouncedFunction,但实际执行的是 doSomething 函数,并且在延迟时间内多次调用会重新计时,只有在延迟时间后才会执行 doSomething 函数。

  • 这样可以确保在需要控制某个函数执行频率的场景下,防抖函数可以帮助避免频繁触发,提升性能和用户体验。

// 防抖函数
function debounce(func, delay) {let timeoutId;return function() {const context = this;const args = arguments;clearTimeout(timeoutId);timeoutId = setTimeout(() => {func.apply(context, args);}, delay);};
}// 示例:模拟一个需要防抖的函数
function doSomething() {console.log('Doing something important!');
}// 创建防抖函数
const debouncedFunction = debounce(doSomething, 1000); // 设置延迟时间为1000毫秒// 调用防抖函数
debouncedFunction(); // 第一次调用
debouncedFunction(); // 在1000毫秒内再次调用
debouncedFunction(); // 在1000毫秒内再次调用

二、什么是节流

定义: 与防抖类似,用于控制某个函数在短时间内被频繁调用的情况
特点:

  • 控制执行频率:节流会确保目标函数在一定时间间隔内只执行一次,即使触发事件多次也不会立即执行,而是在规定的时间间隔后执行。

  • 固定时间间隔:与防抖不同,节流在规定的时间间隔内始终按照固定频率执行函数,不会重新计时。

应用:

  • 页面滚动事件:在处理页面滚动事件时,通过节流可以限制触发频率,比如实现图片懒加载或滚动加载数据。

  • 窗口调整事件:当用户调整窗口大小时,使用节流可以确保在一定时间间隔内执行相关布局调整或响应式设计操作。

  • 按钮点击事件:类似于防抖,节流也可用于控制按钮点击事件的触发频率,确保在一定时间间隔内只执行一次。

  • 用户输入事件:在需要实时反馈用户输入内容的场景中,通过节流可以控制输入事件的处理频率,避免频繁更新UI。

优点:

  • 性能优化:节流可以有效减少函数执行次数,降低性能开销,提高页面性能和响应速度。

  • 流畅交互:通过控制事件执行频率,节流可以确保用户交互过程更加流畅,避免过多的重复操作。

  • 数据请求控制:在需要向服务器请求数据的场景中,节流可以限制请求频率,减少不必要的数据请求,节省网络流量和服务器资源。

总的来说,节流是一种常用的前端技术,通过控制函数执行频率,可以优化性能、提升用户体验,并广泛应用于各种交互场景中。

案例:
逻辑梳理:

  • 在这个示例中,throttle函数接受两个参数:需要节流的函数 func 和间隔时间 delay。返回一个新的函数,用于包裹原始函数 func,并在间隔时间内限制函数的执行频率。

  • 通过调用 throttle(doSomething, 1000) 创建一个节流函数 throttledFunction,然后可以多次调用 throttledFunction,但实际执行的是 doSomething 函数,并且保证在间隔时间内只执行一次。

  • 这样可以确保在需要控制某个函数执行频率的场景下,节流函数可以帮助限制函数的执行频率,避免过多的函数调用,提升性能和用户体验。

// 节流函数
function throttle(func, delay) {let lastCall = 0;return function() {const now = new Date().getTime();if (now - lastCall >= delay) {func();lastCall = now;}};
}// 示例:模拟一个需要节流的函数
function doSomething() {console.log('Doing something important!');
}// 创建节流函数
const throttledFunction = throttle(doSomething, 1000); // 设置间隔时间为1000毫秒// 模拟连续调用节流函数
throttledFunction(); // 第一次调用
throttledFunction(); // 在1000毫秒内再次调用,不会执行
setTimeout(throttledFunction, 500); // 在500毫秒后调用,不会执行
setTimeout(throttledFunction, 1500); // 在1500毫秒后调用,会执行

防抖和节流

function debounce(func, wait, opts = {}) {let maxWait;if ('maxWait' in opts) {maxWait = opts.maxWait;}let leading = true; // 是否在第一次触发时立即执行let trailing = true; // 是否在最后一次触发后执行let lastCallTime; // 上次调用函数的时间let timeout; // 定时器let lastThis; // 函数执行时的 thislet lastArgs; // 函数执行时的参数let lastInvokeTime; // 上次函数实际被调用的时间// 判断是否应该调用函数let shouldInvoke = function (now) {let sinceLastTime = now - lastCallTime;let sinceLastInvoke = now - lastInvokeTime;return lastCallTime === undefined || sinceLastTime > wait || sinceLastInvoke >= maxWait;}// 执行函数let invokeFunc = function (time) {lastInvokeTime = time; // 记录函数实际被调用的时间func.apply(lastThis, lastArgs); // 执行函数}// 启动定时器let startTimer = function (timerExpired, wait) {timeout = setTimeout(timerExpired, wait);}// 计算剩余等待时间let remainingWait = function (now) {return wait - (now - lastCallTime);}// 最后一次触发后执行函数let trailingEdge = function (time) {timeout = undefined;if (trailing) {invokeFunc(time);}}// 定时器到期后的处理逻辑let timerExpired = function () {let now = Date.now();if (shouldInvoke(now)) {return trailingEdge(now);}startTimer(timerExpired, remainingWait(now));}// 第一次触发时执行函数let leadingEdge = function (time) {lastInvokeTime = time;if (leading) {invokeFunc(time);}startTimer(timerExpired, wait); // 开启定时器,准备执行下一次函数调用}// 返回一个处理防抖逻辑的函数let debounced = function (...args) {lastThis = this;lastArgs = args;let now = Date.now();let isInvoking = shouldInvoke(now);lastCallTime = now;if (isInvoking) {if (timeout === undefined) {leadingEdge(now);}}}return debounced;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Java绩效考核系统源码 springboot员工绩效考核系统源码
  • buu[HCTF 2018]WarmUp(代码审计)
  • AI预测福彩3D采取888=3策略+和值012路一缩定乾坤测试5月27日预测第3弹
  • Word 中将 LaTex 代码渲染为公式的两种方法
  • Windows10映射网络驱动器之后不显示映射盘
  • 视觉SLAM十四讲:从理论到实践(Chapter6:非线性优化)
  • AI 谈“浔川AI翻译机”
  • 基于Android Studio记事本系统
  • vue-封装上下(垂直方向)轮播
  • 【XR806开发板试用】SPI驱动数码管显示
  • 语音深度鉴伪识别项目实战:基于深度学习的语音深度鉴伪识别算法模型(一)音频数据编码与预处理
  • 搭建CMS系统
  • MyBatis的基础操作
  • PHP身份证真伪验证、身份证二、三要素核验、身份证ocr接口
  • 【Redis】 关于列表类型
  • [iOS]Core Data浅析一 -- 启用Core Data
  • 2018天猫双11|这就是阿里云!不止有新技术,更有温暖的社会力量
  • es6
  • export和import的用法总结
  • Golang-长连接-状态推送
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • Java Agent 学习笔记
  • Java 内存分配及垃圾回收机制初探
  • NSTimer学习笔记
  • React中的“虫洞”——Context
  • scrapy学习之路4(itemloder的使用)
  • webpack入门学习手记(二)
  • 阿里云Kubernetes容器服务上体验Knative
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 浮现式设计
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 试着探索高并发下的系统架构面貌
  • 微信小程序设置上一页数据
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • ​ ​Redis(五)主从复制:主从模式介绍、配置、拓扑(一主一从结构、一主多从结构、树形主从结构)、原理(复制过程、​​​​​​​数据同步psync)、总结
  • ​人工智能之父图灵诞辰纪念日,一起来看最受读者欢迎的AI技术好书
  • #if #elif #endif
  • #我与Java虚拟机的故事#连载11: JVM学习之路
  • #职场发展#其他
  • (¥1011)-(一千零一拾一元整)输出
  • (android 地图实战开发)3 在地图上显示当前位置和自定义银行位置
  • (ctrl.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (搬运以学习)flask 上下文的实现
  • (附表设计)不是我吹!超级全面的权限系统设计方案面世了
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (论文阅读32/100)Flowing convnets for human pose estimation in videos
  • (数位dp) 算法竞赛入门到进阶 书本题集
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • .bat批处理(十一):替换字符串中包含百分号%的子串
  • .md即markdown文件的基本常用编写语法
  • .net core 管理用户机密
  • .NET Framework 3.5安装教程