手写-js节流(定时器+时间差两种方式)

news2024/11/16 5:40:19

官方解释:当持续触发事件时,保证一定时间段内只调用一次事件处理函数。

节流实现思路: 实现节流函数, 我们使用定时器是不方便管理的, 实现节流函数我们采用另一个思路

我们获取一个当前时间nowTime, 我们使用new Date().gettime()方法获取, 在设定一个开始时间startTime, 等待时间waitTime

waitTime = interval - (nowTime - startTime), 当前的时间减去开始的时间得到结果, 再使用间隔时间减去这个结果, 就可以得到等待时间

得到等待时间我们在进行判断, 如果等待时间小于等于0, 那么就可以执行回调函数

开始时间startTime我们初始值为0就好, 当第一次执行时, nowTime获取的时间戳是一个非常大的值, 得到的结果waitTime是负值, 所以第一次执行节流函数, 一定会立即执行, 这也符合我们要封装的效果

基础节流函数(时间差的方式):

/**
 * 节流函数
 * @param {function} func 需要节流的目标函数
 * @param {number} interval 执行目标函数的间隔,即多久执行一次目标函数ms
 * 注意:如果初始值为当前时间,则最后一次如果没有达到间隔时间则不会执行
 * */
function throttle(func, interval) {
  // 记录上次执行的时间。如果初始值设置成零,则会首次触发就会执行目标函数,相当于立即执行。
  // let preDoTime = 0;
  let preDoTime = new Date().getTime();
  // 返回函数, 使用闭包使preDoTime变量存在于内存中。
  return function (...args) {
    // 记录调用函数的this指向。
    let _this = this;
    //获取到当前日期
    let currentTime = new Date().getTime();
    if (interval <= currentTime - preDoTime) {// 如果当前时间减去上次执行时间 大于等于设置的时间间隔, 就可以执行目标函数
      func.apply(_this, args)
      preDoTime = currentTime;
    }
  }
}
// 测试程序 start ----
const testFun = function (data) {
  console.log(`console.log---${this.name} --- ${data}`);
}

const resultFun = throttle(testFun, 1500);

for (let i = 0; i <= 5; i++) {
  setTimeout(function () {
    this.name = 'setTimeoutFunc1'
    resultFun(`test${i}`);
  }, (i + 1) * 1000) // 6秒内, 每秒执行一次resultFun函数
}

// 距离上次触发间隔0.5秒
setTimeout(function () {
  this.name = 'setTimeoutFunc2'
  resultFun(`test7`);
}, 8000)
// 测试程序 end ----

初始值为当前时间测试结果:

1b37c47e4b884996ad802ec4b9ed6985.png

 初始值为零测试结果:

6e468fa3d3a24469b2b86facd60f5ffa.png

 节流函数(定时器实现):

/**
 * 节流函数
 * @param {function} func 需要节流的目标函数
 * @param {number} interval 执行目标函数的间隔,即多久执行一次目标函数ms
 * 特点: 首次立即执行
 * */
function throttle(func, interval) {
  let timer = null;
  return function(...args) {
    let _this = this;
    if (!timer) {
      timer = setTimeout(function() {
        func.apply(_this, args);
        timer = null;
      }, interval)
    }
  }
}
// 测试程序 start ----
const testFun = function (data) {
  console.log(`console.log---${this.name} --- ${data}`);
}

const resultFun = throttle(testFun, 1500);

for (let i = 0; i <= 5; i++) {
  setTimeout(function () {
    this.name = 'setTimeoutFunc1'
    resultFun(`test${i}`);
  }, (i + 1) * 1000) // 6秒内, 每秒执行一次resultFun函数
}

// 距离上次触发间隔0.5秒
setTimeout(function () {
  this.name = 'setTimeoutFunc2'
  resultFun(`test7`);
}, 8000)

执行结果:

1326d41366ae423d8dcee9514927bff9.png

节流函数(时间差+定时器 兼顾首次和最后一次)

/**
 * 节流函数
 * @param {function} func 需要节流的目标函数
 * @param {number} interval 执行目标函数的间隔,即多久执行一次目标函数ms
 * 特点: 结合时间差和定时器,做到立即执行的同时,兼顾执行最后一次触发
 * */
function throttle(func, interval) {
  let timer = null;
  let preDoTime = 0;
  return function(...args) {
    // 保存this指向
    let _this = this;
    // 获取当前日期
    let currentTime = +new Date();
    // 计算剩余时间,大于零表示未到执行时间,小于零或者定于零则表示到了执行的时间,可以执行
    let remaining = interval - (currentTime - preDoTime);
    if (remaining <= 0) {
      func.apply(_this, args);
      preDoTime = currentTime;
      // 首次会进入上一个if,首次的时候是没有timer的,所以需要判空
      if(timer) {
        // 如果有定时器存在,就将定时器取消。
        clearTimeout(timer);
        timer = null;
      }
    } else if(!timer) {
      timer = setTimeout(function () {
        // 如果是最后一次则没有执行取消定时器的操作,就会执行当前定时器。
        preDoTime = +new Date(); // 因为是定时器,所以执行日期要重新获取。
        timer = null;
        func.apply(_this, args);
      }, interval)
    }
  }
}
// 测试程序 start ----
const testFun = function (data) {
  console.log(`console.log---${this.name} --- ${data}`);
}

const resultFun = throttle(testFun, 1500);

for (let i = 0; i <= 5; i++) {
  setTimeout(function () {
    this.name = 'setTimeoutFunc1'
    resultFun(`test${i}`);
  }, (i + 1) * 1000) // 6秒内, 每秒执行一次resultFun函数
}

// 距离上次触发间隔0.5秒
setTimeout(function () {
  this.name = 'setTimeoutFunc2'
  resultFun(`test7`);
}, 8000)
// 测试程序 end ----

 测试结果:

f48339c3a53443e587a0bb8330ba6296.png

 

 

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

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

相关文章

[RPC]:Feign远程调用

文章目录 1 RPC框架-Feign1.1 什么是Feign1.2 Feign解决的问题1.2.1 使用RestTemplate发送远程调用代码1.2.2 存在的问题 1.3 Feign如何使用1.3.1 引入依赖 1 RPC框架-Feign 1.1 什么是Feign Feign是一个简化HTTP客户端编写的框架&#xff0c;通过声明式方式将远程服务调用封装…

基于html+css的图展示131

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

Three.js教程:平行光与环境光

推荐&#xff1a;将 NSDT场景编辑器 加入你的3D工具链 其他系列工具&#xff1a; NSDT简石数字孪生 平行光与环境光 本节课通过平行光DirectionalLight (opens new window)和环境光AmbientLight (opens new window)进一步了解光照对应模型Mesh表面的影响。 点光源辅助观察Poin…

管理类联考——英语——技巧篇——新题型——经典方法论

新题型可以说是考研英语独有的考查形式&#xff0c;自2005年起&#xff0c;阅读理解部分便新增了PartB&#xff0c;即新题型。之所以叫作新题型&#xff0c;原因很简单&#xff0c;是因为它在考研英语的各个题型中&#xff0c;年龄是最小的&#xff0c;也就是最新的题型。新题型…

【MySQL表的增删改查】

MySQL表的增删改查 1. CRUD2. 新增&#xff08;Create&#xff09;2.1 单行数据 全列插入2.2 多行数据 指定列插入 3. 查询&#xff08;Retrieve&#xff09;3.1 全列查询3.2 指定列查询3.3 查询字段为表达式3.4 别名3.5 去重&#xff1a;DISTINCT3.6 排序&#xff1a;ORDER …

Hibernate框架【一】——HIbernate框架介绍

系列文章目录 Hibernate框架【三】——基本映射——一对一映射 Hibernate框架【四】——基本映射——多对一和一对多映射 Hibernate框架【五】——基本映射——多对多映射 Hibernate框架介绍 系列文章目录前言一、什么是HIbernate框架Hibernate架构图Hibernate提供的核心功能和…

php-xhprof 学习历程

听说 php-xhprof 可以分析网站的性能。今天闲来无事&#xff0c;就学习了一下。 1、安装&#xff08;万事都得从安装开始&#xff09; #首先&#xff0c;他是需要 graphviz 支持的。所以&#xff0c;我们得先安装这个依赖 yum install graphviz #就只需要这一行命令即可#下载地…

【C++】函数重载及引用

目录 一、函数重载 1、函数重载的概念 2、名字修饰 二、引用 1、引用概念 2、引用特性 3、常引用 4、引用的使用场景 4.1 做参数 4.2 做返回值 5、传值、传引用效率比较 6、引用和指针的区别 一、函数重载 1、函数重载的概念 函数重载&#xff1a;是函数的一种特殊情况&#…

leetcode415. 字符串相加

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【LeetCode】 &#x1f353;希望我们一起努力、成长&#xff0c;共同进步。 题目链接 给定两个字符串形式的非负整数 num1 和num2 &#…

OpenCV项目开发实战-- 的单应性(Homography)实例Python/C++代码实现

文末附基于Python和C++两种方式实现的测试代码下载链接 什么是单应性(Homography)? 考虑图 1 中所示的平面(书的顶部)的两个图像。红点表示两个图像中的相同物理点。在计算机视觉术语中,我们称这些为对应点。图 1. 显示了四种不同颜色的四个对应点——红色、绿色、黄色和…

【运维知识进阶篇】zabbix5.0稳定版详解1(安装+部署+添加服务器+拆分数据库)

本篇文章介绍zabbix监控&#xff0c;监控是对我们操作系统进行不间断的监控&#xff0c;这是软件生命周期非常重要的一环&#xff0c;可以做到事前告警&#xff0c;事后根据监控内容排查问题&#xff08;金丝雀&#xff0c;监控重要指标&#xff09;&#xff0c;有问题的时候&a…

chatgpt赋能python:Python安装和设置环境变量教程

Python安装和设置环境变量教程 Python是一门非常流行的编程语言&#xff0c;很多开发者都喜欢使用它开发各种应用程序。作为使用Python编程的开发者&#xff0c;你需要安装Python并设置环境变量。在本文中&#xff0c;我们将向你介绍如何安装Python&#xff0c;以及如何设置环…

c++11 标准模板(STL)(std::basic_ios)(二)

定义于头文件 <ios> template< class CharT, class Traits std::char_traits<CharT> > class basic_ios : public std::ios_base 类 std::basic_ios 提供设施&#xff0c;以对拥有 std::basic_streambuf 接口的对象赋予接口。数个 std::basic_ios…

Jenkins pipeline 执行工程目录里的脚本文件

jenkins 工程根目录下有一个脚本文件&#xff0c;如图所示 文件中有一个简单的输出 我们希望在jenkins pipeline 中执行这个脚本文件&#xff0c;如何配置jenkins pipe 命令呢 首先&#xff0c;要明确一点&#xff0c;我们在jenkins pipeline 中&#xff0c;默认是在Jenki…

英语中如何表达各行各业

前言 &#x1f3e0;个人主页&#xff1a;我是沐风晓月 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是沐风晓月&#xff0c;阿里云社区博客专家 &#x1f609;&#x1f609; &#x1f495; 座右铭&#xff1a; 先努力成长自己&#xff0c;再帮助更多的人,一起加油进…

字符串--从函数返回字符串指针

许多字符串处理函数是不需要返回值的&#xff0c;但实际上它们都被设计成了有返回值的函数。例如字符串赋值函数的函数原型为&#xff1a; char *strcpy(char *str1, const char *str2);字符串连接函数strcat()的函数原型为&#xff1b; char *strcat(char *str1,const char …

springboot+vue+java旅行社旅游网站g748u

使用Spring作为项目管理工具对系统的设计与实现各个模块进行管理,优化代码结构。后台采用Java语言开发,前台页面和后台管理页面使用Bootstrap,JSP,JavaScript,HTML,CSS等技术开发,使用MySql作为数据持久化存储工具对系统的设计与实现的用户等角色权限对应的功能等进行存储。使用…

图像细化原理

1. 图像细化原理 Zhang-Suen 算法原理 Zhang-Suen 算法每运行一次&#xff0c; 需要遍历所有的不为0的像素。在对每个像素&#xff08;P1&#xff09;进行删除或保留的判断时&#xff0c;我们需要关注其周围的8个邻居像素&#xff08;P2, P3, P4, P5, P6, P7, P8&#xff09;的…

012、数据库管理之cluster部署

cluster部署 硬件要求操作系统要求依赖包要求部署的组件 部署集群前置检查安装TiUP组件初始化集群拓扑文件执行部署命令查看集群情况查看已部署的集群情况启动集群验证集群运行状态 启动与停止启动停止 案例讲解测试环境准备环境实施部署 硬件要求 组件CPU内存本地存储网络实例…

大学英语六级考试2022年6月真题|9:00

目录 第一套听力 第一套阅读 选词填空 长篇阅读 仔细阅读 错因 翻译 第一套听力 -7.1 * 1 14/15 -14.2 * 1 9/10 -21.3分 第一套阅读 选词填空 形容词前用副词修饰 remedy vt.修正&#xff1b;纠正 n.解决方法&#xff1b;改进措施 offspring …