防抖debounce与节流throttle(63rd)

news2024/11/30 0:40:06

一、前言

当用户高频触发某一事件时,如窗口的resize、scroll,输入框内容校验等,此时这些事件调用函数的频率如果没有限制,可能会导致响应跟不上触发,出现页面卡顿,假死现象。此时,我们可以采用防抖(debounce) 和 节流(throttle) 的方式来减少调用频率,同时又不影响实际效果。

本质上是优化高频率执行代码的一种手段

二、防抖

防抖:就是指触发事件后,函数在 n 秒后只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数的执行时间。

简单的说,当一个函数连续触发,只执行最后一次。

案例理解

防抖的场景:小谢催小尹还钱,小尹决定三天后还小谢的钱,但是小谢催款的话,小尹就重新计算这个三天的期限,20号催款,23还,21号再催,就24号还。除非小谢这三天没有催小尹还钱。

函数防抖一般用在什么情况之下呢?一般用在,连续的事件只需触发一次回调的场合。具体有:

1、搜索框搜索输入。只需用户最后一次输入完,再发送请求;
2、用户名、手机号、邮箱输入验证;
3、浏览器窗口大小改变后,只需窗口调整完后,再执行resize事件中的代码,防止重复渲染。

代码实现

在下面这段代码中,我们实现了最简单的一个防抖函数,我们设置一个定时器,你重复调用一次函数,我们就清除定时器,重新定时,直到在设定的时间段内没有重复调用函数。

// fn是你要调用的函数,delay是防抖的时间
function debounce(fn, delay) {
  // timer是一个定时器
  let timer = null;
  // 返回一个闭包函数,用闭包保存timer确保其不会销毁,重复点击会清理上一次的定时器
  return function () {
    // 调用一次就清除上一次的定时器
    clearTimeout(timer);
    // 开启这一次的定时器
    timer = setTimeout(() => {
      fn();
    }, delay)
  }
}

代码优化

仔细一想,上面的代码是不是有什么问题?

问题一: 我们返回的fn函数,如果需要事件参数e怎么办?事件参数被debounce函数保存着,如果不把事件参数给闭包函数,若fn函数需要e我们没给,代码毫无疑问会报错。

问题二: 我们怎么确保调用fn函数的对象是我们想要的对象?你发现了吗,在上面这段代码中fn()函数的调用者是fn所定义的环境,这里涉及this指向问题,想要了解为什么可以去了解下js中的this。
为了解决上述两个问题,我们对代码优化如下

// fn是你要调用的函数,delay是防抖的时间
function debounce(fn, delay) {
  // timer是一个定时器
  let timer = null;
  // 返回一个闭包函数,用闭包保存timer确保其不会销毁,重复点击会清理上一次的定时器
  return function () {
    // 保存事件参数,防止fn函数需要事件参数里的数据
    let arg = arguments;
    // 调用一次就清除上一次的定时器
    clearTimeout(timer);
    // 开启这一次的定时器
    timer = setTimeout(() => {
      // 若不改变this指向,则会指向fn定义环境
      fn.apply(this, arg);
    }, delay)
  }
}

三、节流

节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效

简单来说节流就是限制一个函数在一段时间内只能执行一次,过了这段时间,在下一段时间又可以执行一次。

案例理解
节流的场景:小尹催小谢还钱,小谢决定三天内还小尹的钱,就算小尹这三天怎么催,小谢都会在第一次听到要还钱后的第三天,把钱还了。20号第一次催款,不论21,22号有没有催,小谢都会在23号把钱还给小尹。

应用场景如:

1、输入框的联想,可以限定用户在输入时,只在每两秒钟响应一次联想。
2、搜索框输入查询,如果用户一直在输入中,没有必要不停地调用去请求服务端接口,等用户停止输入的时候,再调用,设
置一个合适的时间间隔,有效减轻服务端压力。
3、表单验证
4、按钮提交事件。

代码实现

// 时间戳 & 定时器方法
function throttle(fn, delay) {
  // 初始化定时器
  let timer = null;
  // 上一次调用时间
  let prev = null;
  // 返回闭包函数
  return function () {
    // 现在触发事件时间
    let now = Date.now();
    // 触发间隔是否大于delay
    let remaining = delay - (now - prev);
    // 保存事件参数
    const args = arguments;
    // 清除定时器
    clearTimeout(timer);
    // 如果间隔时间满足delay
    if (remaining <= 0) {
      // 调用fn,并且将现在的时间设置为上一次执行时间
      fn.apply(this, args);
      prev = Date.now();
    } else {
      // 否则,过了剩余时间执行最后一次fn
      timer = setTimeout(() => {
        fn.apply(this, args)
      }, delay);
    }
  }
}

四、区别

相同点:

1、都可以通过使用 setTimeout 实现
2、目的都是,降低回调执行频率。节省计算资源

不同点:

1、函数防抖,在一段连续操作结束后,处理回调,利用clearTimeout和 setTimeout实现。函数节流,在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能

2、函数防抖关注一定时间连续触发的事件,只在最后执行一次,而函数节流一段时间内只执行一次

例如,都设置时间频率为500ms,在2秒时间内,频繁触发函数,节流,每隔 500ms 就执行一次。防抖,则不管调动多少次方法,在2s后,只会执行一次
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/41369.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度剖析NIKE Web3平台:为什么Web3对品牌很重要?

欢迎关注沉睡者IT&#xff0c;点上面关注我 ↑ ↑ 上周&#xff0c;NIKE 宣布了其新的 Web 3 平台 .SWOOSH&#xff0c;这是 NIKE Virtual Sudios (耐克虚拟工作室) 的一项新举措&#xff0c;将成为 NIKE 所有数字资产创作的“大本营”。继去年收购 RTFKT 之后&#xff0c;此次…

SpringBoot SpringBoot 原理篇 3 核心原理 3.4 启动流程【3】

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 原理篇 文章目录SpringBootSpringBoot 原理篇3 核心原理3.4 启动流程【3】3.4.1 看源码咯3 核心原理 3.4 启动流程【3】 …

负载均衡反向代理下的webshell上传

目录 架构如下&#xff1a; 实验环境&#xff1a; AntSword-Labshttps://github.com/AntSwordProject/AntSword-Labs 搭建环境&#xff1a; 启动环境&#xff1a; 测试连接&#xff1a; 地址不停的在漂移会造成的问题&#xff1a; 难点一&#xff1a;我们需要在每一台节点…

特征工程(六)—(2)利用LDA进行特征转换

1、LDA的手动处理 LDA&#xff08;线性判别分析&#xff09;是特征变换算法&#xff0c;也是有监督分类器。 和PCA一样&#xff0c;LDA的目标是提取一个新的坐标系&#xff0c;将原始的数据集投影到一个低维的空间中。 和PCA的主要区别是&#xff0c;LDA不会专注数据的方差&a…

[附源码]计算机毕业设计JAVA实验教学过程管理平台

[附源码]计算机毕业设计JAVA实验教学过程管理平台 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM my…

【Hack The Box】linux练习-- Magic

HTB 学习笔记 【Hack The Box】linux练习-- Magic &#x1f525;系列专栏&#xff1a;Hack The Box &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f4c6;首发时间&#xff1a;&#x1f334;2022年11月21日&#x1f334; &#x1f36…

Js逆向教程17-极验滑块 实现加密算法的逻辑

Js逆向教程17-极验滑块 实现加密算法的逻辑 还是和上节课一样&#xff0c;针对这个网址 https://www.geetest.com/demo/slide-float.html 一、加密算法的结果查看 计算u运行后的结果&#xff1a; a45a0551c344b03be428cab551f9755f073e64061c35988a29d6ba70e7d35c8b9e963b63…

全波形反演的深度学习方法: 第二章 正演 (草稿)

本章介绍正演的基础知识. 本贴的目的是进行内部培训, 错误之处较多, 希望不要误导读者. 2.1 弦线波动基本原理 波动方程是正演的基础. 最简单的模型是在一根弦上的波动, 假设如下: 横震动. 例如拨动吉他弦;微小震动. 满足 u(xΔx,t)−u(x,t)≪Δxu(x \Delta x, t) - u(x, t…

Redis学习(三)之 分布式锁详解

1、redis分布式锁相关的可以移步这篇文章redis做分布式锁实战案例详解_酒书的博客-CSDN博客 这里是对该篇文章的加深与补充 2.集群主从切换导致锁丢失问题&#xff1a;在redis主从架构中&#xff0c;写入都是写入到主redis中&#xff0c;主redis会同步数据到slave机器&#x…

Mybatis插件机制

什么是插件机制 插件插件&#xff0c; 就是能在执行某个方法之前加入一些功能代码&#xff0c; 有啥方法能够实现呢&#xff1f;当然是动态代理了&#xff0c; 为啥要使用动态代理应为他是为了写框架扩展性必备的东西。 只要定义一些接口 或者类 就行使用jdk自带的或者CGLIB之…

分布式NoSQL数据库HBase实践与原理剖析(二)

title: HBase系列 第五章 HBase核心原理 5.1 系统架构 注意&#xff0c;其实上图中的HLog应该在HRegionServer里面&#xff0c;而不是在HRegion里面。所以图有点点问题。其实通过后面的物理存储的图也能发现这个问题。 Client 职责 1、HBase 有两张特殊表&#xff1a; .meta.…

力扣 21. 合并两个有序链表 C语言实现

题目描述&#xff1a; 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 题目链接 方法1&#xff1a;遍历 新建一个链表 newList 用于存放合并后的链表&#xff0c;设置一个指针指向该链表最后一个位置的 next&#xff0c…

77.【JavaWeb文件上传和邮件发送04】

JavaWeb(二十五)、文件上传1.准备工作2.实用类介绍3.思维导图:4.正戏开始5.完整代码(二十六)、邮箱发送1.邮箱发送的原理:2.服务器的原理3.下载两个jar包4.基本类:5.全部代码(二十七)、网站注册发送邮件实现(二十五)、文件上传 1.首先创建一个empty项目 2.配置project项目中的…

【JVM】jvm中的栈简介

jvm中的栈简介一、JVM体系结构二、栈是什么&#xff1f;三、栈的特性四、栈帧五、栈的运行原理5.1 运行原理5.2 代码示例5.2.1 方法的入栈和出栈5.2.2 没有捕获异常5.2.3 捕获异常六、栈帧的内部结构七、运行时数据区&#xff0c;哪些部分存在Error和GC&#xff1f;八、本文源码…

boot 创建 https

需要在配置文件中&#xff1a;加入 server:ssl:key-store: classpath:https.keystorekey-store-type: JKSkey-alias: tomcatkey-password: 123456key-store-password: 123456port: 8089 这样原本请求的http&#xff0c;就需要变成https&#xff0c;其他类似 RestController p…

深度学习入门(五十六)循环神经网络——循环神经网络RNN

深度学习入门&#xff08;五十六&#xff09;循环神经网络——循环神经网络RNN前言循环神经网络——循环神经网络RNN课件潜变量自回归模型循环神经网络使用循环神经网络的语言模型困惑度&#xff08;perplexity&#xff09;梯度裁剪更多的应用RNNs总结教材1 无隐状态的神经网络…

周赛总结--LeetCode单周赛321场 AcWing79场

1. LeetCode单周赛321场 1.1 找出中枢整数 1.1.1 原题链接&#xff1a;力扣https://leetcode.cn/problems/find-the-pivot-integer/ 1.1.2 解题思路&#xff1a; 1、先保存 1-n 的和sum&#xff1b; 2、从 1 开始枚举&#xff0c;判断前 i 项和 cmp 与 sum - cmp i 是否相等…

MySQL第二弹

目录​​​​​​​ 一、数据库基本操作 1、查看数据库信息 2、查看数据库中的表信息 3、显示数据表的结构&#xff08;字段&#xff09; 4、常见的数据类型 4.1 数值类型 4.2 日期和时间类型 4.3 字符串类型 二、SQL语言概述 1、SQL语言 2、SQL分类 2.1 DDL:数据定…

【强化学习论文合集】NeurIPS-2021 强化学习论文

强化学习&#xff08;Reinforcement Learning, RL&#xff09;&#xff0c;又称再励学习、评价学习或增强学习&#xff0c;是机器学习的范式和方法论之一&#xff0c;用于描述和解决智能体&#xff08;agent&#xff09;在与环境的交互过程中通过学习策略以达成回报最大化或实现…

js——高阶函数、闭包、递归以及浅拷贝和深拷贝

目录 一、高阶函数 1、什么是高阶函数 2、把一个函数作为参数 3、return 返回的也是一个函数 二、闭包 1、闭包是什么 2、变量的作用域 3、案例 4、结果展示&#xff1a; 5、总结&#xff1a; 三、递归 1、什么是递归 2、案例一 3、分析 4、问题 5、栈溢出又是什…