什么是防抖与节流?应用场景举例

news2024/12/26 23:46:37
  • 防抖
  • 节流
  • 如何处理防抖与节流
    • 防抖
    • 节流
    • 防抖例子
    • 节流例子
    • Vue + Axios全局接口防抖、节流封装实现
  • 小结

防抖

防抖:触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间

应用场景: 提交按钮、用户注册时候的手机号验证、邮箱验证

假设我们有一个登录按钮,如果用户在短时间内多次点击登录按钮,防抖技术可以防止系统误认为这是多次登录请求,而只将其视作一次有效的登录操作。

节流

节流:高频事件触发,但在n秒内只会执行一次,所以 节流会稀释函数的执行频率

应用场景: window对象的resize、scroll事件 拖拽时候的mousemove 射击游戏中的mousedown、keydown事件 文字输入、自动完成的keyup事件

在窗口调整、页面滚动或者抢购等场景中,我们可能就需要使用节流来控制事件的执行频率,以防止资源的浪费。

更多详细内容,请微信搜索“前端爱好者戳我 查看

如何处理防抖与节流

防抖和节流是两种常见的优化技术,用于防止函数被过度调用。

防抖

对于 防抖 ,可以采用以下方式进行处理:

在函数被触发后,先不立即执行函数,而是设置一个 延迟时间,比如n秒。

如果在延迟时间内再次触发了该函数,则重新计算执行时间。只有在延迟时间内没有再次触发函数,才执行函数。

节流

对于节流,可以采用以下方式进行处理:

同样在函数被触发后,先不立即执行函数,而是设置一个时间间隔,比如每n秒执行一次函数。

这样无论函数被触发的频率有多高,只有每n秒内的第一次触发会被执行。

具体实现防抖和节流的代码,可以参考以下示例代码:

// 防抖
function debounce(fn, delay) {  
  let timer = null;  
  return function() {  
    clearTimeout(timer);  
    timer = setTimeout(() => {  
      fn.apply(this, arguments);  
    }, delay);  
  };  
}

在防抖函数中,我们首先定义了一个定时器变量 timer。

在函数被触发时,先清除上一次的定时器,然后设置一个新的定时器,延迟指定时间后执行函数 fn。

这样就实现了在一段时间内只执行一次函数的效果。

// 节流
function throttle(fn, delay) {  
  let timer = null;  
  return function() {  
    if (!timer) {  
      timer = setTimeout(() => {  
        fn.apply(this, arguments);  
        timer = null;  
      }, delay);  
    }  
  };  
}

在节流函数中,我们同样定义了一个定时器变量 timer。

在函数被触发时,检查定时器是否已经存在,如果不存在,则设置一个新的定时器,延迟指定时间后执行函数 fn。

这样就实现了在一段时间内只执行一次函数的效果。

防抖例子

对于短时间内频繁点击或输入的事件触发,未使用防抖处理的事件对于用户体验并不是很好。因此我们可以使用防抖进行处理,如下:

<div class="box">
  进行防抖处理的:<input type="text" id="name" name="name">
</div>
<script>
  // 模仿一段ajax请求
  function ajax(value){
    console.log("ajax request: " + value + ", time: " + new Date());
  }
 
  // 防抖函数
  function debounce(func,delay){
    let timeout; //定时器
    return function(arguments){
      // 判断定时器是否存在,存在的话进行清除,重新进行定时器计数
      if(timeout) clearTimeout(timeout);//清除之前的事件
      timeout = setTimeout(()=>{
        func.call(this,arguments);//执行事件
      },delay);
    }
  }
 
  const inputBox = document.getElementById("name");
  // 使用防抖函数进行封装ajax
  let debounceAjax = debounce(ajax,500);
  inputBox.addEventListener("keyup",e=>{
    debounceAjax(e.target.value);
  })
</script>

从上面的运行结果可以看出,在500ms内输入文字按下键盘都不会触发请求事件,而是在输入框的定时器500ms停止输入后发送请求。

实现原理很简单,就是对于频繁输入的输入框请求事件添加定时器进行计数,在指定时间内进行频繁输入并不会进行ajax请求,而是在指定时间间隔内停止输入才会执行函数。

当停止输入但在此定时器计数时间内,会重新进行触发请求事件

节流例子

<div class="box">
  进行节流处理的:<input type="text" id="name" name="name">
</div>
<script>
  // 模仿一段ajax请求
  function ajax(value){
    console.log("ajax request: " + value + ", time: " + new Date());
  }
 
  // 节流--定时器版
  function throttle(func,delay){
    let timeout;//定义一个定时器标记
    return function(arguments){
      // 判断是否存在定时器
      if(!timeout){ 
        // 创建一个定时器
        timeout = setTimeout(()=>{
          // delay时间间隔清空定时器
          clearTimeout(timeout);
          func.call(this,arguments);
        },delay)
      }
    }
  }
 
  const inputBox = document.getElementById("name");
  // 使用节流函数进行封装ajax
  let throttleAjax = throttle(ajax,500);
  inputBox.addEventListener("keyup",e=>{
    throttleAjax(e.target.value);
  })
</script>

从上面可以看到,无论我们在输入框输入多少文字,在指定时间内只执行一次函数

Vue + Axios全局接口防抖、节流封装实现

import axios from 'axios'

function request(config) {
    const instance = axios.create({
        baseURL: 'http://localhost:3000/api',
        timeout: 10000
    })

    // 防抖
    const debounceTokenCancel = new Map()
    instance.interceptors.request.use(config => {
    const tokenKey = `${config.method}-${config.url}`
    const cancel = debounceTokenCancel.get(tokenKey)
    if (cancel) {
        cancel()
    }
    return new Promise(resolve => {
        const timer = setTimeout(() => {
            clearTimeout(timer)
            resolve(config)
        }, 800)
        debounceTokenCancel.set(tokenKey, () => {
            clearTimeout(timer)
            resolve(new Error('取消请求'))
        })
      })
    }, error => {
        console.log(error)
        return Promise.reject(error)
    })

    instance.interceptors.response.use(response => {
        return response
    }, error => {
        console.log(error)
        return Promise.reject(error)
    })

    // 节流
    let lastTime = new Date().getTime()
    instance.interceptors.request.use(config => {
        const nowTime = new Date().getTime()
        if (nowTime - lastTime < 1000) {
            return Promise.reject(new Error('节流处理中,稍后再试'))
        }
        lastTime = nowTime
        return config
    }, error => {
        console.log(error)
        return Promise.reject(error)
    })

    return instance(config)
}

export default request

小结

  • 函数防抖和函数节流都是防止某一时间内频繁触发。
  • 函数防抖是在指定时间只执行一次,而函数节流是每到指定间隔时间执行一次。
  • 函数防抖是将几次操作合并为一此操作进行,函数节流使得一定时间内只触发一次函数。

参考链接

  • https://blog.csdn.net/qq_40716795/article/details/123144385
  • https://juejin.cn/post/7225133152490160187

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

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

相关文章

时间序列预测 — CNN-LSTM实现多变量多步光伏预测(Tensorflow)

目录 1 数据处理 1.1 导入库文件 1.2 导入数据集 1.3 缺失值分析 2 构造训练数据 ​3 模型训练 3.1 CNN-LSTM网络 3.2 模型训练 4 模型预测 专栏链接&#xff1a;https://blog.csdn.net/qq_41921826/category_12495091.html 1 数据处理 1.1 导入库文件 import scip…

数据库系统相关概念

数据&#xff1a;描述事务的符号记录。 数据库(DB)&#xff1a;按一定的数据模型组织&#xff0c;描述和存储在计算机内的&#xff0c;有组织的&#xff0c;可共享的数据集合。 数据库管理系统(DBMS)&#xff1a;位于用户和操作系统之间的一层数据管理软件。主要功能包括&#…

(C++)最大连续1的个数--滑动窗口

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能&#xff0c;轻松拿下世界 IT 名企 Dream Offer。https://le…

【LeetCode题目拓展】第207题 课程表 拓展(拓扑排序、Tarjan算法、Kosaraju算法)

文章目录 一、拓扑排序题目二、题目拓展1. 思路分析2. tarjan算法3. kosaraju算法 一、拓扑排序题目 最近在看一个算法课程的时候看到了一个比较好玩的题目的扩展&#xff0c;它的原题如下&#xff1a; 对应的LeetCode题目为 207. 课程表 这个题目本身来说比较简单&#xff…

C# WPF上位机开发(增强版绘图软件)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们写过一个绘图软件&#xff0c;不过那个比较简单&#xff0c;主要就是用鼠标模拟pen进行绘图。实际应用中&#xff0c;另外一种使用比较多的…

【flutter对抗】blutter使用+ACTF习题

最新的能很好反编译flutter程序的项目 1、安装 git clone https://github.com/worawit/blutter --depth1​ 然后我直接将对应的两个压缩包下载下来&#xff08;通过浏览器手动下载&#xff09; 不再通过python的代码来下载&#xff0c;之前一直卡在这个地方。 如果读者可以…

C++11 【初识】

C11简介 1.在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1)&#xff0c;使得C03这个名字已经取代了C98称为C11之前的最新C标准名称。 2.不过由于C03(TC1)主要是对C98标准中的漏洞进行修复&#xff0c;语言的核心部分则没有改动&#xff0c;因此人们习惯性的把两个标准合…

【vtkWidgetRepresentation】第十期 vtkAngleRepresentation标注角度

很高兴在雪易的CSDN遇见你 前言 本文分享VTK中的角度标注,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO AngleRepresentation 目录 前言 1. vtkAngleRepresentatio

Windows使用selenium操作浏览器爬虫

以前的大部分程序都是操作Chrome&#xff0c;很少有操作Edge&#xff0c;现在以Edge为例。 Selenium本身是无法直接控制浏览器的&#xff0c;不同的浏览器需要不同的驱动程序&#xff0c;Google Chrome需要安装ChromeDriver、Edge需要安装Microsoft Edge WebDriver&#xff0c…

直面双碳目标,优维科技携手奥意建筑打造绿色低碳建筑数智云平台

优维“双碳”战略合作建筑 为落实创新驱动发展战略&#xff0c;增强深圳工程建设领域科技创新能力&#xff0c;促进技术进步、科技成果转化和推广应用&#xff0c;根据《深圳市工程建设领域科技计划项目管理办法》《深圳市住房和建设局关于组织申报2022年深圳市工程建设领域科…

二叉搜索树基本概念与实现

目录 基本概念 模拟实现 完整代码 基本概念 根的左节点比根小 根的右节点比根大 左右子树都满足 搜索二叉树的中序遍历是升序 模拟实现 完整代码 #pragma oncetemplate<class K> struct BSNode {BSNode<K>* _left;BSNode<K>* _right;K _val;BSNode(c…

【C语言程序设计】循环结构程序设计

目录 前言 一、程序设计第一题 二、程序设计第二题 三、程序设计第三题 总结 &#x1f308;嗨&#xff01;我是Filotimo__&#x1f308;。很高兴与大家相识&#xff0c;希望我的博客能对你有所帮助。 &#x1f4a1;本文由Filotimo__✍️原创&#xff0c;首发于CSDN&#x1f4da…

1.函数递归起(复习)

1.debug版本可以调试,realse版本不能调试 2.在realse版本中,代码已经得到了优化(编译器可能会自作主张地对代码进行优化),在大小和速度上都是最优的 3.ctrl F5 是开始执行不调试 4.设置好断点后,用F5到达该断点,相当于是到达了该断点的那个位置程序就先停止运行了 5.设立断…

Linux shell编程学习笔记35:seq

0 前言 在使用 for 循环语句时&#xff0c;我们经常使用到序列。比如&#xff1a; for i in 1 2 3 4 5 6 7 8 9 10; do echo "$i * 2 $(expr $i \* 2)"; done 其中的 1 2 3 4 5 6 7 8 9 10;就是一个整数序列 。 为了方便我们使用数字序列&#xff0c;Linux提供了…

UDS DTC状态掩码/DTC状态位

文章目录 简介用途依赖知识1、测试&#xff08;test&#xff09;2、操作循环&#xff08;operation cycle&#xff09;3、老化&#xff08;aging&#xff09; DTC状态位1、Bit 0&#xff1a;Test Failed2、Bit 1&#xff1a;Test Failed This operation cycle3、Bit 2&#xff…

【大数据】Hadoop生态未来发展的一些看法

大数据的起源 谷歌在2003到2006年间发表了三篇论文&#xff0c;《MapReduce: Simplified Data Processing on Large Clusters》&#xff0c;《Bigtable: A Distributed Storage System for Structured Data》和《The Google File System》介绍了Google如何对大规模数据进行存储…

基于51单片机的语音识别控制系统

0-演示视频 1-功能说明 &#xff08;1&#xff09;使用DHT11检测温湿度&#xff0c;然后用LCD12864显示&#xff0c;语音播放&#xff0c;使用STC11l08xe控制LD3320做语音识别&#xff0c; &#xff08;2&#xff09;上电时语音提示&#xff1a;欢迎使用声音识别系统&#xf…

数据结构篇-顺序表及单项链表

目录 一、学习目标 二、顺序表 1. 线性表 1.1 概念 1.2 举例 2. 顺序表 2.1 基本概念 2.2 基本操作 2.3 顺序表优缺点总结 三、单项链表 1. 基本概念 2. 链表的分类 无头节点&#xff1a; 有头节点&#xff1a; 增添加节点 查找节点 删除节点 链表遍历 销毁链…

【ARM Trace32(劳特巴赫) 使用介绍 13 -- Trace32 断点 Break 命令篇】

文章目录 1. Break.Set1.1 TRACE32 Break1.1.1 Break命令控制CPU的暂停1.2 Break.Set 设置断点1.2.1 Trace32 程序断点1.2.2 读写断点1.2.2.1 变量被改写为特定值触发halt1.2.2.2 设定非值触发halt1.2.2.4 变量被特定函数改写触发halt1.2.3 使用C/C++语法设置断点条件1.2.4 使用…

折点计数 C语言xdoj46

问题描述 给定n个整数表示一个商店连续n天的销售量。如果某天之前销售量在增长&#xff0c;而后一天销售量减少&#xff0c;则称这一天为折点&#xff0c;反过来如果之前销售量减少而后一天销售量增长&#xff0c;也称这一天为折点&#xff0c;其他的天都不是折点。如图…