文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

JavaScript定时器setTimeout、setInterval使用详解

2023-05-17 20:47

关注

定时器:按我个人理解来说就是固定某个时间后,时间到了,就提醒我时间到了。

程序中的定时器:相当于倒计时,也相当于计时器。作用是在设定的某个时间后,执行特定的方法。

我们先来了解一下setTimeout定时器,他的特点就是只能用一次,也称为一次性定时器。

setTimeout( func, time, argument1, argument2, .... );
语法解析: 
  1、func:固定时间后执行的方法
  2、time:设置固定的时间-按毫秒计算
  3、argument:传入方法的参数

案例:

    setTimeout(function(name,gender){
        console.log(name + " is " + gender);
    }, 1000, "Tom", "boy");

简写:

    setTimeout((name,gender) => {
        console.log(name + " is " + gender);
    }, 1000, "Tom", "boy");

案例解析:
开启了一个一次性定时器,1秒后执行我给定的函数。

接着看看 setInterval定时器,他的特点就是可以重复执行给定的函数。

console.log("1 ===>");

setTimeout(function(name,gender){
    console.log(name + " is " + gender);
}, 1000, "Tom", "boy");

console.log("2 ===>");

执行结果:
> "1 ===>"
> "2 ===>"
> "Tom is boy"

接下来就开始圈重点了:

定时器概念了解了,也会造定时器了,那这个定时器什么时候调用呢,因为我们的 javaScript代码是从上到下,逐行执行,那到了定时器这行我们的进程会不会等定时器执行完了再执行定时器后面的代码呢?答案是不会等!

遇到定时器,会将定时器加入到任务队列中(宏任务),等所有代码执行完了,程序会看一下队列中还有什么没有完成的 ,如果有没完成的,就执行一下。

这样说可能有点抽象,看下案例好了。

console.log("1 ===>");

setTimeout(function(name,gender){
    console.log(name + " is " + gender);
}, 1000, "Tom", "boy");

console.log("2 ===>");

执行结果:
> "1 ===>"
> "2 ===>"
> "Tom is boy"

注意:任务队列里的执行顺序是按先来后到的

接下来再深入理解一下,我们先思考一个问题,一次性定时器和重复性定时器区别在哪,不可能就只是调一次和调多次这么简单吧。

提醒:接下来的内容比较重要,有点抽象但需要理解透彻

案例:假设我们需要每隔一秒控制台输出一句话。

结合我们本文的学习,给出思路:

1、一次性定时器的函数里再调定时器,形成循环。

2、开启一个重复性定时器

编写实现代码:

思路1:

setTimeout(function run(name,gender){
  console.log(" hello");
  setTimeout(run,1000);
}, 1000);

思路2:

setInterval(()=>{
	console.log("hello")
},1000);

看到这大家可能会不禁感叹,就这?就这?这哪复杂了,逗我呢。

那不妨思考一下,第二个一次性定时器啥时候开始执行呢?第三个呢?第n个呢?程序运行的第n秒?

那我稍微改造一下刚刚的案例好了

let start = Date.now(); // 程序一运行的时间
let times = []; // 用来记录运行时间的数组

let sTime = setInterval(()=>{
  times.push(Date.now() - start); // 记录下执行时间
  if (start + 5000 < Date.now()) {
    console.log(times);
  }
},1000);

接着可以思考一下输出的结果是什么。

然后再来思考重复性定时器,第二次函数调用是啥时候执行呢?第三个呢?第n个呢?

再稍微改造一下好了

let start = Date.now(); // 程序一运行的时间
let times = []; // 用来记录运行时间的数组

let sTime = setInterval(()=>{
  times.push(Date.now() - start); // 记录下执行时间
  if (start + 5000 < Date.now()) {
    console.log(times);
  }
},1000);

好了,留些时间思考一下…

思考好了吗,好了的话一起揭晓一下答案吧。

第一种情况:
> "1 ===>"
> "2 ===>"
> "1 ===>"
> "2 ===>"

第二种情况:
> Array [1001, 2003, 3003, 4000, 5000, 6000]

分析:
情况1:思考这个问题就可 -> 输出 "1 ===>" 之后我开启了另一个定时器,此时是不是应该再输出"1 ===>"?

然后就进入了定时器循环,结果一直只有"1 ===>"?

结合我们的结果,可以发现下一个定时器是什么时候开的?没错,执行完第一个定时器函数内的代码后再执行的。

情况2:根据时间的间隔很容易知道时间就是1秒上下几毫秒,所以下一个定时器是第一个定时器时间结束后立即开启的。

这就是他们两个比较靠底层的区别。

总结的话就留给大家自己总结吧,毕竟一千个读者就会有一千个读者(哈哈,开个玩笑,说句可能像话的话?)。

现在我们已经大致了解了定时器以及触发时间,那么会造定时器了不会取消就有点说不过去了,下面一起看看怎么取消定时器。

let timerId1 = setTimeout(...);
clearTimeout(timerId1); // 取消一次性定时器,timeId1 是唯一且必传参数

let timerId2 = setInterval(...);
clearInterval(timerId2)。 // 取消重复定时器,timeId2 是唯一且必传参数

注意:定时器开启了一定要关闭,要做到有始有终,不然会一直消耗内存,到时候就就很容易程序崩溃。

还有一个留最后讲的,因为比较细节。

下面我们来看个案例

let start = Date.now();
let times = [];

setTimeout(function run() {
  times.push(Date.now() - start); // 保存前一个调用的延时

  if (start + 50 < Date.now()) console.log(times); // 100 毫秒之后,显示延时信息
  else setTimeout(run); // 否则重新调度
});

结果:

> Array [1, 2, 4, 5, 9, 13, 18, 22, 27, 32, 36, 42, 46, 50, 55]
let start = Date.now(); // 程序一运行的时间
let times = []; // 用来记录运行时间的数组

let sTime = setInterval(()=>{
  times.push(Date.now() - start); // 记录下执行时间
  if (start + 50 < Date.now()) {
    console.log(times);
    clearInterval(sTime); // 清除定时器
  }
});

结果:

> Array [1, 2, 3, 4, 8, 13, 16, 20, 25, 28, 32, 36, 40, 44, 48, 53]

感兴趣的同学可以分别思考一下这两组数组的规律,然后再往下看

好了,这就不卖关子了,直接把结论告诉大家吧

浏览器会将 setTimeout 或 setInterval 的五层或更多层嵌套调用(调用五次之后)的最小延时限制在 4ms。这是历史遗留问题。

最后,大家拷贝案例执行的时候,运行的结果很大概率和我这个结果不一样,影响的因素有浏览器版本、类型等等问题。不过这也不影响结论是正确的 

总结

到此这篇关于JavaScript定时器setTimeout、setInterval使用的文章就介绍到这了,更多相关定时器setTimeout、setInterval使用内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯