0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

简述javascript定时器工作原理

jf_78858299 来源:全栈开发者中心 作者:全栈开发者中心 2023-04-21 14:32 次阅读

说到 javascript 中的定时器,我们肯定会想到 setTimeout() 和 setInterval() 这两个函数。本文将从事件循环(Event Loop) 的角度来分析两者的工作原理和区别。

**setTimeout()**

MDN对 setTimeout 的定义为:

在指定的延迟时间之后调用一个函数或执行一个代码片段。

语法

setTimeout 的语法非常简单,第一个参数为回调函数,第二个参数为延时的时间。函数返回一个数值类型的ID唯一标示符,此ID可以用作 clearTimeout 的参数来取消定时器:

var timeoutID = window.setTimeout(code, delay);

IE0+ 还支持回调参数的传入:

var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);

setInterval()

MDN 对 setInterval 的定义为:

周期性地调用一个函数(function)或者执行一段代码。

由于 setInterval 和 setTimeout 的用法一样,所以这里不再列出。

对第二个参数(delay)的说明

由于javascript 的事件循环机制,导致第二个参数并不代表延迟delay毫秒之后立即执行回调函数,而是尝试将回调函数加入到事件队列。实际上,setTimeout 和 setInterval 在这一点上处理又存在区别:

  • setTimeout:延时delay毫秒之后,啥也不管,直接将回调函数加入事件队列。
  • setInterval: 延时delay毫秒之后,先看看事件队列中是否存在还没有执行的回调函数(setInterval的回调函数),如果存在,就不要再往事件队列里加入回调函数了。

所以,当我们的代码中存在耗时的任务时,定时器并不会表现的如我们所想的那样。

通过一个例子来理解

下面的代码,本来希望能够在 100ms 和 200ms 的时候(也就是刚好等待 100ms)调用回调函数:

var timerStart1 = now();
setTimeout(function () {
  console.log('第一个setTimeout回调执行等待时间:', now() - timerStart1);

  var timerStart2 = now();
  setTimeout(function () {
    console.log('第二个setTimeout回调执行等待时间:', now() - timerStart2);
  }, 100);
}, 100);
// 输出:
// 第一个setTimeout回调执行等待时间: 106
// 第二个setTimeout回调执行等待时间: 107

这样的结果看上去正是我们所想的那样,但是一旦我们在代码中加入了耗时的任务时候,结果就不像我们所期望的那样了:

var timerStart1 = now();
setTimeout(function () {
  console.log('第一个setTimeout回调执行等待时间:', now() - timerStart1);

  var timerStart2 = now();
  setTimeout(function () {
    console.log('第二个setTimeout回调执行等待时间:', now() - timerStart2);
  }, 100);

  heavyTask();  // 耗时任务
}, 100);

var loopStart = now();
heavyTask(); // 耗时任务
console.log('heavyTask耗费时间:', now() - loopStart);

function heavyTask() {
  var s = now();
  while(now() - s < 1000) {
  }
}

function now () {
  return new Date();
}
// 输出:
// heavyTask耗费时间: 1015
// 第一个setTimeout回调执行等待时间: 1018
// 第二个setTimeout回调执行等待时间: 1000

两个 setTimeout 的等待事件由于耗时任务的存在不再是 100ms 了!我们来描述一下事情的经过:

  1. 首先,第一个耗时任务(heavyTask())开始执行,它需要大约 1000ms 才能执行完毕。
  2. 从耗时任务开始执行,过了 100ms, 第一个 setTimeout 的回调函数期望执行,于是被加入到事件队列,但是此时前面的耗时任务还没执行完,所以它只能在队列中等待,直到耗时任务执行完毕它才开始执行,所以结果中我们开的看到的是: 第一个setTimeout回调执行等待时间:1018。
  3. 第一个 setTimeout 回调一执行,又开启了第二个 setTimeout, 这个定时器也是期望延时 100ms 之后能够执行它的回调函数。但是,在第一个 setTimeout 又存在一个耗时任务,所有它的剧情跟第一个定时器一样,也等待了 1000ms 才开始执行。

可以用下面的图来概括:

图片

再来看 setInterval 的一个例子:

var intervalStart = now();
setInterval(function () {
  console.log('interval距定义定时器的时间:', now() - loopStart);
}, 100);

var loopStart = now();
heavyTask();
console.log('heavyTask耗费时间:', now() - loopStart);

function heavyTask() {
  var s = now();
  while(now() - s < 1000) {
  }
}

function now () {
  return new Date();
}
// 输出:
// heavyTask耗费时间: 1013
// interval距定义定时器的时间: 1016
// interval距定义定时器的时间: 1123
// interval距定义定时器的时间: 1224

上面这段代码,我们期望每隔 100ms 就打出一条日志。相对于 setTimeout 的区别, setInterval 在准备把回调函数加入到事件队列的时候,会判断队列中是否还有未执行的回调,如果有的话,它就不会再往队列中添加回调函数。 不然,会出现多个回调同时执行的情况。

可以用下面的图来概括:

图片

总结

上面对javascript定时器执行原理进行了简要的分析,希望能够帮助我们更深入的理解javascript。文中有描述不当的地方可以在评论中指出。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 定时器
    +关注

    关注

    23

    文章

    3147

    浏览量

    112037
  • 函数
    +关注

    关注

    3

    文章

    3868

    浏览量

    61309
  • javascript
    +关注

    关注

    0

    文章

    511

    浏览量

    53403
收藏 人收藏

    评论

    相关推荐

    单片机定时器工作原理是什么

    单片机定时器工作原理是什么,在刚开始学习单片机的时候,那时候由于简单的51单片机资源比较少所以一直就觉得单片机的定时器资源不够用。在深度学习各种知识后发现其实很多情况下并不需要那么多定时器
    发表于 07-14 07:14

    定时器的基本工作原理

    一、定时器的基本概述通过滴漏和漏沙瓶这两个例子简单讲述定时器的基本工作原理。STM32的常见的定时器资源:系统嘀嗒定时器SysTick、看门
    发表于 08-02 08:45

    STM32定时器工作原理及分类

    STM32—定时器知多少这里写目录标题STM32---定时器知多少定时器的分类定时器工作原理定时器的应用
    发表于 08-02 09:36

    STM32 Systick定时器简介工作原理

    STM32---Systick定时器简介工作原理Systick寄存SysTick 控制和状态寄存- CTRLSysTick 重装载数值寄存
    发表于 08-19 07:09

    定时器工作原理

    标准库3.5实现:《嵌入式-STM32开发指南》第二部分 基础篇 - 第4章 定时器4.1定时器工作原理STM32有三类定时器,基本定时器
    发表于 08-19 07:49

    STM32通用定时器的基本工作原理是什么

    STM32的常见的定时器有哪几种呢?通用定时器的基本结构是由哪些部分组成的?STM32通用定时器的基本工作原理是什么?
    发表于 11-24 06:25

    定时器\计数中断的工作原理

    (1)工作原理定时和计数可以一样理解,设置一定的数量,满足条件进行中断,这个满足条件成为溢出。(2)如何配置定时器\计数中断:对TMOD赋值,以确定T0和T1的
    发表于 12-07 09:49

    PLC定时器工作原理是什么?

    咨询一下PLC定时器工作原理,谢谢。
    发表于 11-01 07:43

    看门狗定时器工作原理

    看门狗定时器工作原理:WDT 工作原理使能时,WDT 将递增,直到溢出,或称“超时”。除非处于休眠或空闲模式,WDT 超时会强制器件复位。为避免WDT 超时复位,用户必须定期用PW
    发表于 10-06 09:33 134次下载

    555定时器内部框图及电路工作原理

     本文介绍555定时器内部框图及电路工作原理: 555定时器内部框图 555集成时基电路称为集成定时
    发表于 11-22 13:00 7.6w次阅读
    555<b class='flag-5'>定时器</b>内部框图及电路<b class='flag-5'>工作原理</b>

    定时器/计数器的结构和工作原理

    定时器/计数器的结构和工作原理 定时器/计数器的结构  定时器/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器组成
    发表于 03-29 09:08 1.9w次阅读
    <b class='flag-5'>定时器</b>/计数器的结构和<b class='flag-5'>工作原理</b>

    555定时器工作原理及应用引脚图

    介绍555定时器工作原理及应用引脚图. 和了解最基本电路
    发表于 12-23 11:16 16次下载

    单片机计数器_定时器工作原理_

    单片机计数器_定时器工作原理定时器、计数器寄存器,以及定时器的四种工作方式。
    发表于 05-06 14:12 1次下载

    51单片机定时器工作原理

    51单片机定时器工作原理及用法
    的头像 发表于 03-14 13:51 9.3w次阅读

    简述555定时器设计数字时钟

    简述555定时器设计数字时钟
    发表于 10-08 16:26 21次下载