函数的节流和防抖?节流和防抖的区别及实现

news2024/9/20 16:59:08

一.防抖和节流的本质

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

比如说:浏览器的scroll,keypress,mousemove,resize等事件在触发时,会不断的调用绑定在事件上的回调函数,会极大地浪费资源,降低前端的性能。

因此为了优化用户体验,需要对这类事件进行调用次数的限制,我们可以采用throttle(节流)和debounce(防抖)的方式来减少调用频率。

二.定义

节流:单位时间内(n秒)只运行一次,若在单位时间内(n秒)内重复触发,只有一次执行;

防抖:单位时间后(n秒)再执行该事件,若在单位时间内(n秒)被重复触发,则重新计时。

打个比喻来说明一下:

想象每天在办公楼乘坐的电梯,把电梯完成一次运送,类比为一次函数的执行和响应。

假设电梯有两种运行方式:防抖和节流,超时设定为10秒。第一个人进来电梯后,10秒后准时运送一次,这就是节流;当电梯打开进来一人后,等待10秒。如果在这10秒内又有人进来了,10秒等待重新计时,直到10秒后开始运行,这就是防抖。

三.用代码实现一下

(1)节流

完成节流可以使用时间戳与定时器的写法。使用时间戳写法,事件会立即执行,停止触发后函数没有办法再次执行。

 function throttled(fn, delay = 500) {
            let timestamp1 = Date.now()
            return function (...args) {
                let timestamp2 = Date.now()
                if (timestamp2 - timestamp1 >= delay) {
                    fn.apply(null, args)
                    timestamp1 = Date.now()
                }
            }
        }

然后使用定时器写法,500毫秒后第一次执行,第二次事件触发后依然会再一次执行。

  function throttled(fn, delay = 500) {
            let timestamp = null
            return function (...args) {
                if (!timestamp) {
                    timestamp = setTimeout(() => {
                        fn.apply(this, args)
                        timestamp = null
            }, delay)
         }
      }
   }

也可以将时间戳写法的特性和定时器写法相结合,实现一个更好的节流函数:

  function throttled(fn, delay = 500) {
            let timestamp = null
            let starttime = Date.now()
            return function () {
                let currentTime = Date.now()//当前时间
                let remaintime = delay - (currentTime - starttime)//从上一次到现在,还剩下多少剩余时间
                let self = this
                let args = arguments
                clearTimeout(timestamp)
                if (remaintime <= 0) {
                    fn.apply(self, args)
                    starttime = Date.now()
                } else {
                    timestamp = setTimeout(fn, remaintime)
                }
            }
        }

(2)防抖

1.简单实现的方式:

    function debounce(fn, waittime) {
            let timestamp
            return function () {
                let self = this//保存this指向
                let args = arguments//获取到事件对象
                clearTimeout(timestamp)
                timestamp = setTimeout(function () {
                    fn.apply(self, args)
                }, waittime)
            }

        }

2.防抖立即执行的话,可加入第三个参数用于判断

  function debounce(fn, waittime, immediate) {
            let timestamp
            return function () {
                let self = this//保存this指向
                let args = arguments//获取到事件对象
                if (timestamp) clearTimeout(timestamp)//timestamp不为空
                if (immediate) {
                    let rightNow = !timestamp//第一次会立即执行,以后只有事件执行后才会再次触发
                    timestamp = setTimeout(function () {
                        timestamp = null
                    }, waittime)
                    if (rightNow) {
                        fn.apply(self, args)
                    }
                } else {
                    timestamp = setTimeout(function () {
                        fn.apply(self, args)
                    }, waittime)
                }

            }

        }

三.防抖和节流的区别

(1)相同点

都可以通过setTimeout实现;

目的都是降低回调执行频率。

(2)不同点

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

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

例如:都设置时间频率为500毫秒,在2秒时间内,频繁触发函数,节流会每隔500毫秒就执行一次。而防抖,则不管调用多少次方法,在2秒后,只会执行一次。

看张图:

 

四.应用场景

1.防抖在连续的事件,只需触发一次回调的场景有:

搜索框搜索输入。只需要用户最后一次输入完,再发送请求;

手机号及邮箱验证输入检测;

窗口大小resize。只需要窗口调整完成后,计算窗口大小。防止重复渲染。

2.节流在间隔一段时间执行一次回调的场景有:

滚动加载。加载更多或滚到底部监听.

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

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

相关文章

【C++模板】非类型模板参数

目录什么是非类型模板参数&#xff1f;非类型的类模板参数非类型的函数模板参数非类型模板参数的局限性限制使用的场景支持使用的场景什么是非类型模板参数&#xff1f; 在函数模板和类模板中&#xff0c;模板参数并不仅仅可以当作类型&#xff0c;还可以当作普通值。当使用普通…

Numpy解决找出二维随机矩阵中每行数据中最接近某个数字的数字

解决思路&#xff1a; 利用np.random.rand()函数生成随机的矩阵。abs函数实现对矩阵中每一个元素和指定元素相减np.argsort()函数实现找到排序后新元素在原来矩阵中的下标利用mask函数提取矩阵中第一列的元素最后利用for循环遍历所有的二维坐标&#xff0c;找到矩阵中每行中满…

微信小程序-读取数据

在开发微信小程序的时候,我们经常都会用到一些配置数据,或者当做“单向数据库(只读)”使用。 我们新建一个新的项目工程,JS版本就可以。 免于麻烦,我们新建一个page(showdata)来显示数据。 为了方便管理,我们在项目工程新建一个目录(data),用于存数据。另外我们再新…

面向对象-05-06-构造方法,标准的 javabean 类

实例化的本质就是调用构造方法 package com.luo.demo01;public class StudenTest {public static void main(String[] args) {// 创建对象// 本质&#xff1a;调用构造器Student s new Student();Student student new Student("luo",18);System.out.println(studen…

Git系列,自定义 git 命令,用 shell 脚本帮助你更好的实现 git 版本控制

一、问题引出 在实际的生产当中&#xff0c;无论是 git、小乌龟 git 、idea git 插件&#xff0c;都满足不了我们生产中遇到的一些常见的问题&#xff0c;例如&#xff1a; 工作任务重的时候&#xff0c;手头上可能有若干个分支&#xff0c;每个分支对应着不同的业务&#xf…

Mysql面试题汇总

Mysql面试题 文章目录Mysql面试题一 Mysql索引001 Mysql如何实现的索引机制&#xff1f;002 InnoDB索引与MyISAM索引实现的区别是什么&#xff1f;003 一个表中如果没有创建索引&#xff0c;那么还会创建B树吗&#xff1f;004 说一下B树索引实现原理&#xff08;数据结构&#…

妙啊,Python 管道 Pipe 编写代码如此优雅

大家好&#xff0c;今天这篇文章我将详细讲解 Pipe 如何让你的代码更加简洁的方法&#xff0c;喜欢本文点赞支持&#xff0c;欢迎收藏学习&#xff0c;文末提供技术交流群&#xff0c;欢迎畅聊&#xff01; 我们知道 map 和 filter 是两种有效的 Python 方法来处理可迭代对象。…

如何基于YAML设计接口自动化测试框架?看完秒会!

在设计自动化测试框架的时候&#xff0c;我们会经常将测试数据保存在外部的文件&#xff08;如Excel、YAML、CSV&#xff09;或者数据库中&#xff0c;实现脚本与数据解耦&#xff0c;方便后期维护。目前非常多的自动化测试框架采用通过Excel或者YAML文件直接编写测试用例&…

[附源码]计算机毕业设计springboot招聘系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

电子学会2021年6月青少年软件编程(图形化)等级考试试卷(四级)答案解析

青少年软件编程&#xff08;图形化&#xff09;等级考试试卷&#xff08;四级&#xff09; 分数&#xff1a;100.00 题数&#xff1a;24 一、单选题&#xff08;共10题&#xff0c;每题3分&#xff0c;共30分&#xff09; 1. 执行下列程序&#xff0c;输出的结果为…

bert 环境搭建之PytorchTransformer 安装

这两天跑以前的bert项目发现突然跑不了&#xff0c;报错信息如下&#xff1a; Step1 transformer 安装 RuntimeError: Failed to import transformers.models.bert.modeling_bert because of the following error (look up to see its traceback): module signal has no att…

IOT物联网系统架构

主要由 IotCloodServer物网联服务平台&#xff0c; IotAdminWeb物联网管理平台&#xff0c; IotDataProcessing物联网数据平台&#xff0c; IotDeviceGateway物联网边缘网关&#xff0c; IotDeviceToolHepler物联网边缘网关 控制 设备的工具类&#xff0c; IotApp物联网应…

SpringBoot_整合Mybatis

一 导入依赖 <!--整合mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.3</version></dependency><dependency><group…

ubuntu20.04屏幕亮度无法调节的解决方法->安装 brightness-controller-simple 软件

文章目录一、问题描述二、解决方法参考链接一、问题描述 安装ubunt20.04.5 之后&#xff0c;调节Ubuntu上方的亮度控制条、按快捷键(FnF5、FnF6) 都不能实现调节亮度的功能。 二、解决方法 安装 brightness-controller-simple 软件&#xff0c;利用软件调节亮度。 sudo add…

论文投稿指南——中文核心期刊推荐(计算机技术2)

>>>深度学习Tricks&#xff0c;第一时间送达<<< 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊。下面&#xff0c;简单介绍下什么是中文核心期刊要目总览&#xff1a; 《中文核心期刊要目总…

Web安全专业学习路线

最专业、全面的网络安全学习路线来咯~&#xff08;虽然是网络安全学习路线&#xff0c;但重心还是在Web安全上&#xff09; 展示学习路线之前&#xff0c;建议大家先了解一下这几个问题&#xff0c;既是认清形势&#xff0c;也是认清自我&#xff1a; 为什么要学网络安全&…

期末测试——JavaScript方式练习题

练习目标&#xff1a; 技术简介&#xff1a; js外部引入顺序结构jQuery Dom操作JavaScrip循环技巧JavaScrip数据操作资源地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1VZMGTKj3Aq9Zn6mtee0egw 提取码&#xff1a;1111 关键字&#xff1a; 1、append()&#x…

高分辨率遥感卫星影像在交通方面的应用及高分二号影像获取

高分辨率遥感影像在城市交通领域具有广泛的应用前景&#xff1a;如遥感交通调查、遥感影像地图与电子地图制作、道路工程地质遥感解译、交通安全与知道抗灾救灾、交通事故现场快速勘察、交通需求预测、车辆与车牌视频识别等等。高分辨率影像比如高分二号卫星、高分一号卫星&…

基于蝙蝠算法实现电力系统经济调度(Matlab代码实现)

目录 摘要&#xff1a; 1.蝙蝠优化算法的基本原理&#xff1a; 2.蝙蝠优化算法的流程&#xff1a; 3.仿真实验分析&#xff1a; 摘要&#xff1a; 基于Matalb平台&#xff0c;构建基于蝙蝠活动行为的蝙蝠优化算法&#xff0c;对一个含有6个火电机组的电力系统进行优化调度…

redis6.2(二)Redis的新数据类型、使用java语言操作Redis

redis的安装配置、基本数据类型可以参考: redis6.2&#xff08;一&#xff09;安装、配置、常用数据类型 5、Redis的新数据类型 (1) Bitmaps Redis提供了Bitmaps这个“数据类型”可以实现对位的操作&#xff1a; &#xff08;1&#xff09; Bitmaps本身不是一种数据类型&am…