js事件循环机制

2023-05-16

一、同步任务与异步任务

JavaScript是一门单线程语言,但是单线程并不意味着阻塞。实现单线程非阻塞的方式就是事件循环机制。在JavaScript中,所有的事件都可以分为同步任务和异步任务。

同步任务:立即执行的任务。同步任务一般会直接进入到主线程执行。

异步任务:异步执行的任务,比如ajax请求、setTimeout定时器等。

任务进入执行栈,会先判断当前任务是同步任务还是异步任务,如果是同步任务则会进入到主线程,立即执行;异步任务会先放到Event Table,注册回调函数到Event Queue。等待所有的同步任务执行完后,主线程会去Event Queue中读取异步任务到主线程中执行,这个过程的不断重复就是事件循环

二、微任务与宏任务

异步任务分为微任务和宏任务:

微任务:一个需要异步执行的函数,执行时机是在主函数结束之后,当前宏任务结束之前。常见的微任务有:Promise.then、MutationObserver、Object.observe(已废弃,被Proxy对象替代)、process.nextTick

宏任务:宏任务的时间粒度比较大,执行的时间间隔是不能精确控制的,对一些高实时性的需求就不太符合。常见的宏任务有:script(外层同步代码)、setTimeout/setInterval、UI rendering/UI事件、postMessage、MessageChannel、setImmediate、I/O(Node.js)

微任务和宏任务的执行机制:

执行一个宏任务,如果遇到微任务就将它放到微任务的事件队列中;当前宏任务执行完成后,会查看微任务的事件队列,然后将里面的所有微任务依次执行完。

例题:

console.log(1)①
setTimeout(()=>{
    console.log(2)②
},0)
new Promise((resolve,reject)=>{
   console.log('new Promise')③
   resolve()
}).then(()=>{
   console.log('then')④
})
console.log(3)⑤

执行过程为:

(1)①是同步任务,直接打印1,

(2)②为宏任务,

(3)③是同步任务,直接打印'new Promise',

(4)④是微任务,放入微任务队列,后面再执行

(5)⑤是同步任务,直接打印3.

(6)本轮宏任务执行完毕,现在去微任务列表查看是否有微任务,④是微任务,执行打印'then'

(7)一次宏任务执行完,再去执行新的宏任务,即定时器宏任务,打印2

所以最终打印的结果是1-->new Promise-->3-->then-->2

三、async与await

async用于声明异步函数,await用于等待异步任务执行

async函数返回一个promise对象,await命令后面是一个Promise对象,返回该对象的结果。如果不是Promise对象,直接返回对应的值,不管await后面跟着什么,都会阻塞后面的代码!!

await的执行机制:

await fn():会立即执行fn(),但是会阻塞fn()后面的代码(加入微任务队列)

例题:

async function async1() {
    console.log('async1 start')①
    await async2()②
    console.log('async1 end')③
}
async function async2() {
    console.log('async2')④
}
console.log('script start')⑤
setTimeout(function () {
    console.log('settimeout')⑥
})
async1()⑦
new Promise(function (resolve) {
    console.log('promise1')⑧
    resolve()
}).then(function () {
    console.log('promise2')⑨
})
console.log('script end')⑩

第一轮循环:先执行⑤,打印出:script start,setTimeout为宏任务,放入宏任务队列;执行⑦,进入async1(),先打印:async1 start,遇到await会阻塞后面的语句执行,所以将③放入微任务队列,立即执行②,打印出async2;Promise.then()为微任务,⑨放入微任务队列,Promise立即执行打印:promise1,接着向下执行打印script end

宏任务:setTimeout

微任务:③、⑨

script start-->async1 start-->async2-->promise1-->script end-->async1 end-->promise2-->settimeout

第一轮宏任务结束,查看微任务队列,执行所有的微任务③⑨,打印promise2,接着下一轮宏任务。

执行setTimeout,打印settimeout。

第二轮宏任务结束,没有要执行的微任务队列,执行③,打印async1 end

最终打印的结果为script start-->async1 start-->async2-->promise1-->script end-->promise2-->settimeout-->async1 end

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

js事件循环机制 的相关文章

  • OPCAutomation_TLB.pas(1240): Cannot assign to a read-only property 问题解决

    OPCAutomation TLB pas 1240 Cannot assign to a read only property 问题解决 http blog csdn net skyjacker 问 xff1a Delphi 6 我注册了
  • VSS Invalid Handle 问题解决

    VSS Invalid Handle 问题解决 在浏览器中打开 VSS 服务器的共享目录 ip folder xff0c 输入用户名和密码登录后 xff0c 再运行客户端即可
  • 程序员自己的定位以及怪物追踪寻路AI (转)

    先从程序员的思想定位开始 程序员是什么 其实我们不是什么高深摸测的数学家 能使用多少种算法 能把计算机玩得那么厉害 其实程序的本质就是一个翻译者 是一个将人类的行为描述成计算机语言的翻译者 在这个解释里面 有一个根本的定位 就是计算机从属于
  • 游戏开发真功夫:游戏开发定律

    游戏开发真功夫 xff1a 游戏开发定律 http www shuzifun com article 56 t 8856 html 发布 2010 4 08 11 18 作者 十二 来源 游戏圈 虽然全球已经有了那么多游戏培训机构和学院 x
  • 游戏开发流程和部分分工

    http blog csdn net njhua123 archive 2009 11 23 4859662 aspx 原创 游戏开发流程和部分分工 收藏 游戏开发流程和部分分工 流程 xff1a 调研 开发 测试 运营 xff08 我们公
  • C++以http接口推送json流和图片流

    一 C 43 43 推送json流 C 43 43 代码 xff1a span class token comment span span class token comment a single threaded multi client
  • subprocess.Popen执行程序以及关闭进程

    python中有一个很好用的方式来开启进程 xff0c 即subprocess Popen 正常来说 xff0c 如果subprocess Popen要执行的脚本是一个死循环的脚本 xff0c 那么我们就需要手动的来关闭这个脚本 xff0c
  • 【Simulink教程案例16】基于simulink的LDPC编译码+16QAM调制解调通信系统性能仿真——输出误码和星座图

    欢迎订阅 FPGA MATLAB SIMULINK系列教程 Simulink教程目录 本课程学习成果预览 目录 1 软件版本 2 LDPC编译码理论简介
  • C++头文件定义全局函数或类成员函数

    C 43 43 头文件定义全局函数或类成员函数 你可能很熟悉C C 43 43 的声明定义规则 xff1a 头文件中声明变量和函数 xff0c 源文件中定义变量和函数 在头文件中定义变量和函数会导致 重定义 xff0c 因为包含该头文件的不
  • 分享几种锂电池均衡电路的工作原理

    新能源的发展 xff0c 电动汽车发展 xff0c 都会用到能量密度比更高的锂电池 xff0c 而锂电池串联使用过程中 xff0c 为了保证电池电压的一致性 xff0c 必然会用到电压均衡电路 在这几年的工作过程中 xff0c 用到过几种电
  • 思岚科技激光雷达全面升级:RPLIDAR A1仅需900元,A2测距提升至8米

    思岚科技自2009年着手研发低成本激光雷达 xff0c 2014年面向全球推出了第一代产品RPLIDAR A1 xff0c 在6米测量半径内 xff0c 可完成每秒2000次激光测距 自推出至今 xff0c 已累计使用用户达上千家 时隔两年
  • 【产品评测】用RPLIDAR A2搭建gmapping

    以我自己的小车mrobot为例 1 硬件环境 xff1a mrobot小车 xff08 采用turtlebot create协议 xff0c 可以用turtlebot xff09 rplidar激光雷达 2 rplidar包下载 git c
  • 如何利用RPLIDAR A2进行多点触摸应用

    1 RPLidar激光雷达套件 2 RPlidar multi touch SDK 请点击 这里 下载 注意事项 注意 此SDK仅适用于RPLiDAR A2 型号 xff0c 其他型号暂不支持 xff0c 请知悉 1 请确保USB线不宜过长
  • ROS机器人编程学习(五)——ROS命令3

    第5章 ROS命令 本章主要讲解了ROS下的常用操作命令 xff0c 包括shell命令 执行命令 信息命令 catkin命令 功能包命令 由于这一章内容实在太多了 xff0c 因此博客分三节进行学习记录 本文主要记录catkin命令和功能
  • 什么是哈希码?它的作用是什么?

    哈希值 哈希算法将任意长度的二进制值映射为固定长度的较小二进制值 xff0c 这个小的二进制值称为哈希值 哈希值是一段数据唯一且极其紧凑的数值表示形式 如果散列一段明文而且哪怕只更改该段落的一个字母 xff0c 随后的哈希都将产生不同的值
  • 队列数据结构详解

    1 队列既可以用链表实现 xff0c 也可以用顺序表实现 跟栈相反的是 xff0c 栈一般用顺序表来实现 xff0c 而队列我们常用链表来实现 xff0c 称为链队列 xff0c 它是后入前出 头结点进 xff0c 尾结点出 xff0c 头
  • 数据结构之树的存储结构

    大家可能都知道 xff0c 存储结构有顺序存储结构和链式存储结构 很明显这两个结构不管哪一个 xff0c 都不能很好的表达数这种数据结构 xff0c 所以我们特此在这说一下数的存储结构 用这个树作为例子 xff1a 树的存储结构分为以下几类

随机推荐

  • 收发多径都考虑的情况

    0 完整源码获得方式 订阅MATLAB FPGA教程 xff0c 免得获得教程案例以及任意2份完整源码 收发多径都考虑的情况 clear all close all clc c 61 3e8 f0 61 150e6 载波频率 fd 61 1
  • Linux进程管理命令

    1 ps命令 ps aux xff1a 查看系统中的所有进程 xff0c 使用BS操作系统格式 ps le xff1a 查看系统中的所有进程 xff0c 使用LINUX标准命令格式 选项 xff1a a xff1a 显示一个终端的所有进程
  • C++信号概念

    信号 xff1a 它是操作系统传给进程的中断 xff0c 用来中断程序 xff0c 在Linux系统和Windows系统上可以用ctr 43 c产生中断信号 一 xff1a 穿插一个linux下各个快捷按键的信号区别 xff1a 1 ctr
  • Linux系统编程

    Linux系统中所见皆文件 bin xff1a 所存放二进制可执行文件 boot xff1a 存放开机启动程序 dev xff1a 存放设备文件 home xff1a 存放用户 etc xff1a 用户信息和系统配置文件 lib xff1a
  • Linux系统编程(续)

    静态库制作及使用步骤 xff1a 1 将 c生成 o文件 gcc c add c o add o 2 使用ar工具制作静态库 ar rcs lib自定义库名 a 后面需要的 c文件 3 编译静态库到可执行文件中 gcc test c 自制的
  • keil 提示internal command error和no sw device

    1 使用keil烧录软件的时候 xff0c jlink stlink无法识别到芯片 需要排查的问题 1 xff09 换条线 2 xff09 是不是有程序禁用了Seral Wire xff1a 使用cubeide cubeMX xff0c 容
  • 【C++】C++使用libcurl做HttpClient

    当使用C 43 43 做HTTP客户端时 xff0c 目前通用的做法就是使用libcurl 其官方网站的地址是http curl haxx se xff0c 该网站主要提供了Curl和libcurl Curl是命令行工具 xff0c 用于完
  • STM32F767 采用FIFO模式串口发送接收

    功能 xff1a 将接收到的数据发送出去 UART HandleTypeDef huart1 span class token punctuation span span class token comment 64 brief The a
  • 单片机串口分析起始位停止位奇偶校验位

    串口解析 串口配置 1 波特率 2 停止位 3 数据位 4 奇偶校验位 比特率 xff1a 通讯的频率停止位 xff1a 可以选择1 1 5 2三个选择数据位 xff1a 可以选择5 6 7 8四个选择奇偶校验位 xff1a 可以选择奇校验
  • 在算法研究过程中如何进行算法创新

    FPGA教程目录 MATLAB教程目录 创新一直是一个令人纠结的话题 xff0c 研究生毕业设计多数需要算法的创新 xff0c 而博士生毕业更需要大量的创新才行 另外一方面 xff0c 一些前沿的课题 xff0c 更是对算法的创新有着较高的
  • GPIO口相关配置寄存器

    STM32的每个Px端口都有四种7个寄存器来控制 xff0c 分别是 xff1a 2个32位的端口输入输出模式寄存器CRL CRH 2个32位的数据寄存器IDR ODR 1个32位的置位 复位寄存器BSRR 1个16位的复位寄存器BRR 1
  • STM32串口接收以及发送大全

    串口接收 xff1a 一 一帧数据以 r n结束 协议理解 xff1a 协议嘛 xff0c 就是我们人为创造一条规则 xff0c 按这条规则规规矩矩地来章程执行能够减少错误 xff0c 效率更高 xff0c 都执行一个规则也能大一统 下面我
  • 51单片机串口奇偶校验

    有的单片机串口奇偶校验都是硬件自动完成的 xff0c 但是就我目前用到的很多51核的单片机 xff0c 需要软件做一些简单的处理来完成奇偶校验 可以自己写一个简单的小程序来实现 xff1a 一位一位的判断1的个数 xff0c 这个当然好实现
  • C语言printf()输出格式大全

    这里写自定义目录标题 1 xff0e 转换说明符 a A 浮点数 十六进制数字和p P 记数法 C99 c 字符 d 有符号十进制整数 f 浮点数 包括float和doulbe e E 浮点数指数输出 e E 记数法 g G 浮点数不显无意
  • 2019年 电赛C题 全国大学生电子设计竞赛试题解析与总结

    2019年全国大学生电子设计竞赛试题 电赛C题 分析与总结 线路负载及故障检测装置 本科组 一 题目任务 设计并制作线路负载及故障检测装置 xff0c 示意图如图1所示 检测装置只通过两个连接端子与两根导线连接 导线上A B两点距离各自连接
  • 用moment获取一年内指定周的起始时间和结束时间、用户所选时间和前端传参时间不一致问题

    问题1 xff1a 原代码 xff1a 所选周 selectedWeek handler let selectedWeek 61 parseInt this selectedWeek substring 1 计算所选周的周开始时间和周结束时
  • HTML知识(一)

    1 HTML元素 HTML元素指的是从开始标签 start tag 到结束标签 xff08 end tag xff09 的所有代码 元素内容是开始标签与结束标签之间的内容 某些HTML元素具有空内容 xff0c 空元素在开始标签中进行关闭
  • CSS隐藏元素、BFC、元素居中、布局

    1 css中有哪些方式可以隐藏页面元素 xff1f 区别是什么 xff1f 1 1 display none 元素在页面上将彻底消失 xff0c 元素本身占有的空间会被其他元素占有 xff0c 导致浏览器的重排和重绘 特点 xff1a 元素
  • 响应式设计和CSS提高性能的方法

    一 响应式设计 1 是什么 xff1f 是一种网络页面设计布局 xff0c 页面的设计与开发应当根据用户行为以及设备环境 xff08 系统平台 屏幕尺寸 屏幕定向等 xff09 进行相应的响应和调整 2 常见特点 xff08 1 xff09
  • js事件循环机制

    一 同步任务与异步任务 JavaScript是一门单线程 语言 xff0c 但是单线程并不意味着阻塞 实现单线程非阻塞的方式就是事件循环机制 在JavaScript中 xff0c 所有的事件都可以分为同步任务和异步任务 同步任务 xff1a