使用react hooks写一个倒计时功能

news/2024/5/19 18:54:56

先要明确的是,setTimeout函数中执行代码的时间肯定是要大于等于setTimeout时间的,那么就可能出现设定的 1 秒,实际执行却执行了 2 秒的情况,那么我们的实现思路也很简单,每次计算一下setTimeout实际执行的时间,然后动态的调整下一次执行的时间,而不是设置固定的值

第n次执行 executionTime 实际执行时间 nextTime 下次需要执行的时间 totleTime 执行的总时间
0 0 1000 0
1 1200 800 1200
2 1100 700 2300
3 1000 700 3300
4 2200 500 5500
5 1300 200 6800
6 1200 1000 8000

const useCountDown = ({ leftTime, ms = 1000, onEnd }) => {const countdownTimer = useRef();const startTimer = useRef();//记录初始时间const startTimeRef = useRef(performance.now());// 第一次执行的时间处理,让下一次倒计时时调整为整数const nextTimeRef = useRef(leftTime % ms);const [count, setCount] = useState(leftTime);const clearTimer = () => {countdownTimer.current && clearTimeout(countdownTimer.current);startTimer.current && clearTimeout(startTimer.current);};const startCountDown = () => {clearTimer();const currentTime = performance.now();// 算出每次实际执行的时间const executionTime = currentTime - startTimeRef.current;// 实际执行时间大于上一次需要执行的时间,说明执行时间多了,否则需要补上差的时间const diffTime =executionTime > nextTimeRef.current? executionTime - nextTimeRef.current: nextTimeRef.current - executionTime;setCount((count) => {const nextCount =count - (Math.floor(executionTime / ms) || 1) * ms - nt;return nextCount <= 0 ? 0 : nextCount;});// 算出下一次的时间nextTimeRef.current =executionTime > nextTimeRef.current ? ms - diffTime : ms + diffTime;// 重置初始时间startTimeRef.current = performance.now();countdownTimer.current = setTimeout(() => {requestAnimationFrame(startCountDown);}, nextTimeRef.current);};useEffect(() => {setCount(leftTime);startTimer.current = setTimeout(startCountDown, nextTimeRef.current);return () => {clearTimer();};}, [leftTime]);useEffect(() => {if (count <= 0) {clearTimer();onEnd && onEnd();}}, [count]);return count;
};export default useCountDown;

http://www.mrgr.cn/p/68800856

相关文章

opencv图片的平移-------c++

图片平移 cv::Mat opencvTool::translateImage(const cv::Mat& img, int dx, int dy) {// 获取图像尺寸int rows img.rows;int cols img.cols;// 定义仿射变换矩阵cv::Mat M (cv::Mat_<float>(2, 3) << 1, 0, dx, 0, 1, dy);// 进行仿射变换cv::Mat dst;cv…

HTTP协议相关文档

HTTP The Hypertext Transfer Protocol (HTTP) is an application-level protocol for distributed, collaborative, hypermedia information systems. bing.com 翻译: 超文本传输协议 (HTTP) 是用于分布式的、协作的、超媒体信息系统的 应用程序级协议。IETF Internet Engi…

YPay源支付Mini Pro免授权使用版v1.0

YPay源支付Mini Pro免授权使用版v1.0 &#xff0c;修改host屏蔽Pro授权站&#xff0c;可有效防止因用户操作不当导致免授权程序无法执行时 执行授权官方的盗版入库代码&#xff0c;尽可能保证网站安全 1.安装SG14组件 注&#xff1a;仅防止二次开发添加授权 2.”/etc/host”文…

ArthasGC日志GCeasy详解

Arthas详解 Arthas是阿里巴巴在2018年9月开源的Java诊断工具,支持JDK6,采用命令行交互模式,可以方便定位和诊断线上程序运行问题.Arthas官方文档十分详细.详见:官方文档 Arthas使用场景 Arthas使用 # github下载arthas wget https://alibaba.github.io/arthas/arthas-boot.j…

Elasticsearch:探索 11 种流行的机器学习算法

作者&#xff1a;来自 Elastic Elastic Platform Team 过去几年中&#xff0c;机器学习&#xff08;ML&#xff09;已经悄然成为我们日常生活中不可或缺的一部分。它影响着从购物网站和流媒体网站上的个性化推荐&#xff0c;到保护我们的收件箱免受我们每天收到的大量垃圾邮件的…

用户中心(下)

文章目录 计划登录逻辑接口简单说明cookie和session写代码流程后端逻辑层控制层测试用户管理接口 前端简化代码对接后端代理 计划 开发完成后端登录功能 &#xff08;单机登录 > 后续改造为分布式 / 第三方登录&#xff09;✔开发后端用户的管理接口 &#xff08;用户的查询…

【Docker学习】docker start深入研究

docker start也是很简单的命令。但因为有了几个选项&#xff0c;又变得复杂&#xff0c;而且... 命令&#xff1a; docker container start 描述&#xff1a; 启动一个或多个已停止的容器。 用法&#xff1a; docker container start [OPTIONS] CONTAINER [CONTAINER...] 别名&…

大数据技术架构

一、hadoop 1、基础知识 1.1、概念 ①Hadoop集群特点&#xff1a;高可靠性、高效性、高可拓展性、高容错性、成本低、运行在Linux操作系统上、支持多种编程语言 ②Hadoop的由来&#xff1a; 谷歌的三驾马车对应的开源软件描述GFS&#xff1a;海量数据怎么存HDFS分布式文件…

C++ | Leetcode C++题解之第61题旋转链表

题目&#xff1a; 题解&#xff1a; class Solution { public:ListNode* rotateRight(ListNode* head, int k) {if (k 0 || head nullptr || head->next nullptr) {return head;}int n 1;ListNode* iter head;while (iter->next ! nullptr) {iter iter->next;n…

力扣每日一题111:二叉树的最小深度

题目 简单 给定一个二叉树&#xff0c;找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明&#xff1a;叶子节点是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;2示例 2&#x…

小程序地理位置接口权限直接抄作业

小程序地理位置接口有什么功能&#xff1f; 随着小程序生态的发展&#xff0c;越来越多的小程序开发者会通过官方提供的自带接口来给用户提供便捷的服务。但是当涉及到地理位置接口时&#xff0c;却经常遇到申请驳回的问题&#xff0c;反复修改也无法通过&#xff0c;给的理由也…

RTT I/O设备模型

I/O设备模型 绝大部分的嵌入式系统都包括一些I/O&#xff08;Input/Output&#xff0c;输入/输出&#xff09;设备&#xff0c;例如仪器上的数据显示屏、工业设备上的串口通信、数据采集设备上用于保存数据的Flash或SD卡&#xff0c;以及网络设备的以太网接口等&#xff0c;都…

TCP的特性(4)

TCP特性 拥塞控制(可靠性机制)延迟应答(效率机制)捎带应答(效率机制)面向字节流(粘包问题)TCP异常机制(心跳包)小结 拥塞控制(可靠性机制) 虽然TCP引入了滑动窗口,能够高效可靠的传输大量数据,但是在开始阶段就发送大量数据,可能引起一系列问题. TCP引入了慢启动机制,先发少量的…

Vue3+.NET6前后端分离式管理后台实战(十七)

1&#xff0c;Vue3.NET6前后端分离式管理后台实战(十七)已经在微信公众号更新&#xff0c;有兴趣的扫码关注一起交流学习。

Learning GitHub Actions Automation and Integration of CI/CD with GitHub【7】

CHAPTER 7 Managing Data Within Workflows 今天,很少有人用一个工作或项目来完成一套完整的工作。考虑一个典型的CI/CD管道。 你通常会有一个做建筑的工作,一个做包装的工作,多个做测试的工作,等等。 但即使这些都是单独的作业,它们仍然需要能够在它们之间传递数据和文件…

Learning GitHub Actions Automation and Integration of CI/CD with GitHub【8】

CHAPTER 8:Managing Workflow Execution 根据定义,GitHub操作工作流更多的是声明性的,而不是命令式的。 这意味着,您不是编写定义如何完成任务的编程逻辑,而是主要通过声明要使用的triggers、jobs、steps和runners来创建工作流。 并且,对于每个步骤,您将定义运行哪些操作…

Learning GitHub Actions Automation and Integration of CI/CD with GitHub【9】

CHAPTER 9:Actions and Security 正如前面几章所看到的,动作提供了令人印象深刻的自动信息水平。 它们还提供了直接在GitHub中完成任务的方法,否则这是不可能的。 然而,这些同样的功能也可能意味着必须事先考虑和计划的安全风险。 否则,您将打开存储库到多个攻击面和漏洞。…

知识图谱在提升大语言模型性能中的应用:减少幻觉与增强推理的综述

幻觉现象指的是模型在生成文本时可能会产生一些听起来合理但实际上并不准确或相关的输出&#xff0c;这主要是由于模型在训练数据中存在知识盲区所致。 为了解决这一问题&#xff0c;研究人员采取了多种策略&#xff0c;其中包括利用知识图谱作为外部信息源。知识图谱通过将信息…

Learning GitHub Actions Automation and Integration of CI/CD with GitHub【4】

CHAPTER 4 : Working with Workflows 我相信您现在已经收集到了,工作流是使用GitHub操作的核心。 我已经介绍了一些理解工作流的基本知识。 但是,您还需要能够轻松地创建、运行和监控它们的成功/失败。 本章将重点介绍这些活动。 首先,我将调查GitHub为从启动程序创建工作流…

Learning GitHub Actions Automation and Integration of CI/CD with GitHub【5】

CHAPTER 5:Runners 无论使用GitHub操作实现什么功能,都必须有一个地方来执行该功能 -- 一个具有足够资源来处理作业的虚拟或物理系统,以及一个配置为在分派作业时与操作控制平面交互的系统。 在操作术语中,在工作流中执行作业的系统被称为运行器。 在高级,跑步器系统有两种…