JavaScript 定时器详解

定时器

​ JavaScript 在浏览器中是单线程执行的,但允许使用定时器指定在某个时间之后或每隔一段时间就执行相应的代码。setTimeout() 用于指定在一定时间后执行某些代码,而 setInterval() 用于指定每隔一段时间执行某些代码。

setTimeout() 方法

​ setTimeout() 方法通常接收两个参数:要执行的代码和在执行回调函数前等待的时间(毫秒)。

​ 第一个参数可以是包含 JavaScript 代码的字符串(类似于传给 eval() 的字符串)或者一个函数,比如:

// 在 1 秒后显示警告框
setTimeout(() => alert("Hello world!"), 1000);

​ 第二个参数是要等待的毫秒数,而不是要执行代码的确切时间。JavaScript 是单线程的,所以每次只能执行一段代码。为了调度不同代码的执行,JavaScript 维护了一个任务队列。其中的任务会按照添加到队列的先后顺序执行。setTimeout() 的第二个参数只是告诉 JavaScript 引擎在指定的毫秒数过后把任务添加到这个队列如果队列是空的,则会立即执行该代码。如果队列不是空的,则代码必须等待前面的任务执行完才能执行

​ 调用 setTimeout() 时,会返回一个表示该超时排期的数值 ID。这个超时 ID 是被排期执行代码的唯一标识符,可用于取消该任务。要取消等待中的排期任务,可以调用 clearTimeout() 方法并传入超时 ID,如下面的例子所示:

// 设置超时任务
let timeoutId = setTimeout(() => alert("Hello world!"), 1000); 
// 取消超时任务
clearTimeout(timeoutId);

​ 只要是在指定时间到达之前调用 clearTimeout(),就可以取消超时任务。在任务执行后再调用 clearTimeout() 没有效果。

注意:所有超时执行的代码(函数)都会在全局作用域中的一个匿名函数中运行,因此函数中的 this 值在非严格模式下始终指向 window,而在严格模式下是 undefined。如果给 setTimeout() 提供了一个箭头函数,那么 this 会保留为定义它时所在的词汇作用域。

setInterval() 方法

​ setInterval() 与 setTimeout() 的使用方法类似,只不过指定的任务会每隔指定时间就执行一次,直到取消循环定时或者页面卸载。setInterval() 同样可以接收两个参数:要执行的代码(字符串或函数),以及把下一次执行定时代码的任务添加到队列要等待的时间(毫秒)。下面是一个例子:

setInterval(() => alert("Hello world!"), 10000); 

注意:这里的关键点是,第二个参数,也就是间隔时间,指的是向队列添加新任务之前等待的时间。比如,调用 setInterval() 的时间为 01:00:00,间隔时间为 3000 毫秒。这意味着 01:00:03 时,浏览器会把任务添加到执行队列。浏览器不关心这个任务什么时候执行或者执行要花多长时间。因此,到了 01:00:06,它会再向队列中添加一个任务。由此可看出,执行时间短、非阻塞的回调函数比较适合 setInterval()。

​ setInterval() 方法也会返回一个循环定时 ID,可以用于在未来某个时间点上取消循环定时。要取消循环定时,可以调用 clearInterval() 并传入定时 ID。相对于 setTimeout() 而言,取消定时的能力对 setInterval() 更加重要。毕竟,如果一直不管它,那么定时任务会一直执行到页面卸载。下面是一个常见的例子:

let num = 0, intervalId = null; 
let max = 10; let incrementNumber = function() { num++; // 如果达到最大值,则取消所有未执行的任务if (num == max) { clearInterval(intervalId); alert("Done"); } 
} intervalId = setInterval(incrementNumber, 500);

​ 在这个例子中,变量 num 会每半秒递增一次,直至达到最大限制值。此时循环定时会被取消。这个模式也可以使用 setTimeout() 来实现,比如

let num = 0; 
let max = 10; let incrementNumber = function() { num++; // 如果还没有达到最大值,再设置一个超时任务if (num < max) { setTimeout(incrementNumber, 500); } else { alert("Done"); } 
} setTimeout(incrementNumber, 500); 

​ 注意在使用 setTimeout() 时,不一定要记录超时 ID,因为它会在条件满足时自动停止,否则会自动设置另一个超时任务。这个模式是设置循环任务的推荐做法。setIntervale() 在实践中很少会在生产环境下使用,因为一个任务结束和下一个任务开始之间的时间间隔是无法保证的,有些循环定时任务可能会因此而被跳过。而像前面这个例子中一样使用 setTimeout() 则能确保不会出现这种情况。一 般来说,最好不要使用 setInterval()。

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

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

相关文章

【前端学习——js篇】5.事件循环

详细&#xff1a;https://github.com/febobo/web-interview 5.事件循环 js是一种单线程语言&#xff0c;同一时间内只能做一件事情&#xff0c;为了避免单线程阻塞的方法就是事件循环。 在javascript当中&#xff0c;所有的任务都可以分为&#xff1a; 同步任务&#xff1a;按…

Windows10 Version22h2 补丁kb5034441更新失败

By wdhuag 20240328 参考: Windows10安装KB5034441更新报错0x80070643_2024-01 适用于 windows 10 version 22h2 安全更新,适合基于 x64 -CSDN博客 windows10&#xff08;KB5034441&#xff09;更新失败报错 0x80070643解决方法_kb5034441更新失败-CSDN博客 如何修复 Windo…

07|Java IO流与网络编程入门教程:通俗易懂,实例丰富

一、IO流概念与应用 什么是IO流? 想象一下水管流水,水从一端流入流出的过程就像是数据在程序中的传输。在Java世界里,IO流就是这样一个抽象概念,它是数据在不同存储介质或网络之间传输的一种方式。简单来说,如果你把数据看作水流,那么IO流就是承载这个水流的管道,它可以…

01.ArcEngine中IField的属性详细描述

目录 0.代码样例 1. AliasName 2.CheckValue 3.DefaultValue 4.Domain 5.DomainFixed 6.Editable 7.GeometryDef 8.IsNullable 9.Length 10.Name 11.Precision 12.Required 13.Scale 14.Type 15.VarType 0.代码样例 IFields fields featureclass…

双通道内存@DDR5多通道内存

文章目录 多通道内存DDR4及以前的内存的双通道DDR5往后的双通道和多通道半位宽4通道组合 其他组合测试 DDR5介绍概览重要Features特点 总结 多通道内存 DDR4及以前的内存的双通道 双通道内存是一种内存架构设计&#xff0c;通过在主板上配置两个或多个独立且同时工作的内存控制…

管理阿里云服务器ECS -- 网站选型和搭建

小云&#xff1a;我已经学会了如何登录云服务器ECS了&#xff0c;但是要如何搭建网站呢&#xff1f; 老王&#xff1a;目前有很多的个人网站系统软件&#xff0c;其中 WordPress 是使用非常广泛的一款&#xff0c;而且也可以把 WordPress 当作一个内容管理系统&#xff08;CMS…

使用yolov9来实现人体姿态识别估计(定位图像或视频中人体的关键部位)教程+代码

yolov9人体姿态识别&#xff1a; 相较于之前的YOLO版本&#xff0c;YOLOv9可能会进一步提升处理速度和精度&#xff0c;特别是在姿态估计场景中&#xff0c;通过改进网络结构、利用更高效的特征提取器以及优化损失函数等手段来提升对复杂人体姿态变化的捕捉能力。由于YOLOv9的…

架构师之路--docker命令实践整理

安装docker sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine sudo yum install -y yum-utils sudo yum-config-manager --add-repo http://mirrors.aliyun.com/…

开源博客项目Blog .NET Core源码学习(12:App.Application项目结构分析)

开源博客项目Blog的App.Application项目主要定义网站页面使用的数据类&#xff0c;同时定义各类数据的增删改查操作接口和实现类。App.Application项目未安装Nuget包&#xff0c;主要引用App.Core项目的类型。   App.Application项目的顶层文件夹如下图所示&#xff0c;下面逐…

巨控GRM110系列:短距离内的无线通讯模块

标签: #巨控GRM110 #无线通讯 #ROLA技术 #工业自动化 #远程数据采集 在工业自动化和智能制造的领域中&#xff0c;数据的准确传输是实现高效生产的关键。随着技术的不断进步&#xff0c;无线通讯技术已成为破解远距离数据传输难题的利器。今天&#xff0c;我们将聚焦于一款革命…

U盘未格式化?数据恢复大揭秘!

在日常办公和生活中&#xff0c;U盘已成为我们不可或缺的数据存储工具。然而&#xff0c;有时我们会遇到这样一个令人头疼的问题&#xff1a;原本正常使用的U盘&#xff0c;突然提示“未格式化”&#xff0c;里面的文件似乎都消失不见了。面对这种情况&#xff0c;很多人会感到…

35岁,程序员职业生涯的新起点

近年来&#xff0c;关于程序员职业生涯的讨论日益热烈&#xff0c;而“35岁被认为是程序员职业生涯的分水岭”更是成为了一个备受关注的话题。在这篇文章中&#xff0c;我们将探讨这一说法的合理性&#xff0c;并从事实和数据的角度来分析&#xff0c;为什么35岁并非程序员职业…

线程池-1:线程池是如何复用线程的?

这段代码实现了一个简单的线程池 SimpleThreadPool。主要包括以下几个关键部分&#xff1a; 构造函数&#xff1a;初始化最大线程数 maxPoolSize、任务队列 taskQueue、当前线程数 currentPoolSize&#xff0c;以及锁 lock 和条件 taskAvailable。 submit(Runnable task) 方法…

PSINS初学指导

2024-3-27/Evand/Ver1 因为惯导解算设计的数学公式很多&#xff0c;在编程时如果一步一步自己编&#xff0c;非常耗时耗力&#xff0c;所以在进行上层设计时&#xff0c;借助工具箱完成底层的复杂计算是很有必要的。另一方面&#xff0c;也能利用工具箱进行惯导解算方面的学习…

FPGA时钟资源详解(2)——Clock-Capable Inputs

FPGA时钟系列文章总览&#xff1a;FPGA原理与结构&#xff08;14&#xff09;——时钟资源https://ztzhang.blog.csdn.net/article/details/132307564 目录 一、概述 1.1 为什么使用CC 1.2 如何使用CC 二、Clock-Capable Inputs 2.1 SRCC 2.2 MRCC 2.3 其他用途 2.3.1…

WIFI驱动移植实验:WIFI驱动加载测试

一. 简介 前面文章学习了向kernel内核源码中添加 trl8188驱动代码&#xff0c;配置内核以支持 WIFI设备&#xff0c;使能WIFI功能。文章地址如下&#xff1a; WIFI驱动移植实验&#xff1a;删除Linux内核自带的 RTL8192CU 驱动-CSDN博客 WIFI驱动移植实验&#xff1a;将 rtl…

LeetCode 135. 分发糖果

n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需要按照以下要求&#xff0c;给这些孩子分发糖果&#xff1a; 每个孩子至少分配到 1 个糖果。相邻两个孩子评分更高的孩子会获得更多的糖果。 请你给每个孩子分发糖果&#xff0c;计算并返回需要准备的…

C语言中连字符“#”的使用,输出固件的编译时间和版本号

首先我们使用C语言宏定义和“#”来组合字符串 #define MAINVER 2#define SUBVER1 0#define SUBVER2 1#define STR(s) #s#define VERSION(a,b,c) "System V" STR(a) "." STR(b) "." STR(c) " "__DATE__ 然后我们在全局变量中定义一…

服务器硬件

目录 服务器CPU服务器GPU服务器内存服务器硬盘服务器主板散热系统&#xff08;服务器风扇&#xff09;服务器电源&#xff08;电影供应器&#xff09;其他网络适配器扩展卡 服务器CPU 基于架构的分类&#xff1a;根据CPU的架构不同&#xff0c;可以分为x86架构&#xff08;如I…

API接口鉴权签名设计

在设计API接口的鉴权签名时&#xff0c;通常会使用一种加密算法来生成签名&#xff0c;以确保请求的合法性和安全性。以下是通过鉴权签名的设计方案。 1、接口秘钥设置 Key:123 Secret:abc 2、接口Url 接口Url需要使用https的协议保证接口数据安全传输 3、请求参数 3.1、…