【JavaScript】一文详解事件循环机制

news2024/12/23 8:45:36

目录

一、是什么

二、同步任务和异步任务

三、宏任务和微任务

小结:微任务是跟屁虫,一直跟着当前宏任务后面代码执行到一个微任务就跟上,一个接着一个。

例子理解:

五、题目巩固

六、总结


一、是什么

首先JavaScript是一种单线程语言,同一时间内只能做一件事情,所有的任务都需要排队完成。这并不意味着单线程就是阻塞,而实现单线程非阻塞的方法就是事件循环。

为什么JavaScript不能有多个线程呢?

        作为浏览器脚本语言,JavaScript的主要用途是与用户互动以及操作dom节点。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,当JavaScript同时有两个线程,一个是在A节点上添加内容,另一个是删除A节点,这个时候浏览器不知道应该以哪个为准。

        为了避免这种复杂性,因此JavaScript只能是单线程。

二、同步任务和异步任务

JavaScript中,所有的任务都可以分为

  • 同步任务:立即执行的任务,同步任务一般会直接进入到主线程中执行
  • 异步任务:异步执行的任务,比如ajax网络请求,setTimeout定时函数等

同步任务进入主线程,即主执行栈,异步任务进入任务队列,主线程内的任务执行完毕为空,会去任务队列读取对应的任务,推入主线程执行。

三、宏任务和微任务

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

常见的宏任务:

  • script(整体代码)
  • setTimeout
  • setInterval
  • postMessage、MessageChannel
  • setImmediate、I/O(Node.js)
  • UI交互事件
  • ajax请求

常见的微任务:

  • Promise.then

  • MutaionObserver

  • process.nextTick(Node.js)

任务的优先级: process.nextTick > promise.then > setTimeout > setlmmediate

小结:微任务是跟屁虫,一直跟着当前宏任务后面代码执行到一个微任务就跟上,一个接着一个。

例子理解:

五、题目巩固

console.log(1)

setTimeout(()=>{
    console.log(2)
}, 0)

new Promise((resolve, reject)=>{
    console.log('new Promise')
    resolve()
}).then(()=>{
    console.log('then')
})

console.log(3)

 流程如下:

// 遇到 console.log(1) ,直接打印 1
// 遇到定时器,属于新的宏任务,留着后面执行
// 遇到 new Promise,这个是直接执行的,打印 'new Promise'
// .then 属于微任务,放入微任务队列,后面再执行
// 遇到 console.log(3) 直接打印 3
// 好了本轮宏任务执行完毕,现在去微任务列表查看是否有微任务,发现 .then 的回调,执行它,打印 'then'
// 当一次宏任务执行完,再去执行新的宏任务,这里就剩一个定时器的宏任务了,执行它,打印 2

六、总结

事件的循环机制规定了执行代码的顺序

  1. 先执行同步代码;
  2. 遇到异步宏任务则将异步宏任务放进宏任务队列中;
  3. 遇到异步微任务则将异步微任务放进微任务队列中;
  4. 当script整体代码所有同步代码执行完毕后,再将异步微任务从【任务队列】中调入【主线程】执行;
  5. 微任务执行完毕后再将异步宏任务从【任务队列】中调入【主线程】执行;微任务再跟着当前宏任务后面,代码执行到一个微任务就跟上,一个接着一个。
  6. 一直循环到所有任务执行完毕。

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

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

相关文章

CAD练习——绘制电路

绘制如图交叉的六条线: 修剪,在右侧绘制如图的线:(平移O) 修剪 效果: 绘制电路触点 B:块编辑器,设置为块 添加触点到其他几个位置(I:插入) 绘制其他电路器件…

【Linux】内核宏定义解释postcore_initcall,arch_initcall,subsys_initcall

postcore_initcall postcore_initcall(pcibus_class_init) 是一个宏,用于在Linux内核初始化过程中注册一个后期初始化函数。 这个宏的含义如下: postcore_initcall 是一个宏定义,用于指定注册的函数在内核初始化的哪个阶段执行。 pcibus_cl…

GOLANG进阶 之 接口(interface) 与 管道(channel)

好久没有跟新过文章了,小编最近有点忙,写文章的频率下降了许多,但是还是会持续跟新的,希望关注的同学仔细学习。 首先讲一下接口具体是个啥?小白可以结合官方定义和小编自己的理解共同学习下 官方解释:接口…

MATLAB程序初始化OpenFOAM颗粒位置

问题引入 在OpenFOAM的颗粒两相流求解器中,我们可以采用manualInjection的方式进行自定义颗粒的初始位置,这个命令十分方便,在CFDEM中也有类似的命令,不过CFDEM中的命令更加强大,我们不仅可以定义颗粒的初始位置&…

Dockerfile 简单实战

将flask项目打包成镜像 1. 准备flask文件 创建 app.py 文件,内容如下 from flask import Flask app Flask(__name__)app.route(/) def hello_world():return Hello Worldif __name__ __main__:app.run(host0.0.0.0, port8000, debugTrue) 并开启外网访问&#xf…

C# 使用FFmpeg.Autogen对byte[]进行编解码

C# 使用FFmpeg.Autogen对byte[]进行编解码,参考:https://github.com/vanjoge/CSharpVideoDemo 入口调用类: using System; using System.IO; using System.Drawing; using System.Runtime.InteropServices; using FFmpeg.AutoGen;namespace F…

云原生是什么

目录 1. 云原生是什么1.1. 微服务1.2. DevOps1.3. 持续交付1.4. 容器化 2. 什么是云原生2.1. 云原生的诞生2.2. 云原生基金会2.3. 主要区别: 云原生与传统企业应用 1. 云原生是什么 云原生是面向"云"而设计的应用, 因此技术部分依赖于传统云计算的 3 层概念, 基础设…

二叉树题目:根据二叉树创建字符串

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 题目 标题和出处 标题:根据二叉树创建字符串 出处:606. 根据二叉树创建字符串 难度 3 级 题目描述 要求 给你二叉树的根结…

Git 代码分支规范

目的 俗话说:没有规矩,不成方圆。遵循一个好的规章制度能让你的工作事半功倍。同时也可以展现出你做事的认真的态度以及你的专业性,不会显得杂乱无章,管理困难。Git分支规范也是一样。当遵循了某种约定的Git分支,在代…

欧拉公式的证明-泰勒展开法

欧拉公式 欧拉公式在理工科有着广泛的应用和影响。 特别地,当时,,巧妙地将自然对数底数 ,圆周率 ,虚数单位 , 写进一个公式。 证明 由泰勒公式: 即 提取奇偶次项: 即 补充&#xf…

Michael.W基于Foundry精读Openzeppelin第23期——ERC165Checker.sol

Michael.W基于Foundry精读Openzeppelin第23期——ERC165Checker.sol 0. 版本0.1 ERC165Checker.sol 1. 目标合约2. 代码精读2.1 supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId)2.2 supportsERC165(address account)2.3 supportsInterface(address acc…

Docker一键部署项目,无需登录XShell

文章目录 一键部署项目Docker手动部署SpringBoot项目编写docker部署的脚本文件script.sh 脚本内容 特别注意!编写dockerfiledockerfile 文件内容 上传后端服务的jar包到服务器中执行 script 脚本部署后端服务 自动部署SpringBoot项目引入jsch依赖编写jsch工具类执行…

C# byte[]与Bitmap互转

首先先观察一下本地bmp图像结构(参考: https://blog.csdn.net/qq_37872392/article/details/124710600): 可以看到bmp图像结构除了纯图像像素点位信息,还有一块未用空间(OffSet)。 所以如果需要得到图像所有数据进行转换,则可以使…

MySQL_SQL性能分析

SQL执行频次 语法: SHOW GLOBAL STATUS LIKE COM_类型; COM_insert; 插入次数 com_delete; 删除次数 com_update; 更新次数 com_select; 查询次数 com_______; 注意:通过语法,可以查询到数据库的实际状态,就可以知道数据库是以增删…

macos搭建appium-iOS自动化测试环境

目录 准备工作 安装必需的软件 安装appium 安装XCode 下载WDA工程 配置WDA工程 搭建appiumwda自动化环境 第一步:启动通过xcodebuild命令启动wda服务 分享一下如何在mac电脑上搭建一个完整的appium自动化测试环境 准备工作 前期需要准备的设备和账号&…

【独立版】新零售社区团购电商系统生鲜水果商城兴盛优选十荟团源码

【独立版】新零售社区团购电商系统生鲜水果商城兴盛优选十荟团源码

DNSlog注入(利用DNSlog平台将SQL盲注变成回显注入)

前言什么是UNC什么是DNSlog注入DNSlog注入的条件防止DNSlog注入的几个措施 sqli-labs试验 前言 前几天面试的时候,面试官问我知不知道OOB(带外数据)。 当时我蒙了,确实没听说过这个东西,然后面试官告诉我原来dnslog注入…

机器人CPP编程基础-04输入Input

机器人CPP编程基础-03变量类型Variables Types ……AI…… C #include<iostream> // 引入iostream库&#xff0c;这个库包含了对输入/输出进行操作所需的函数和对象 using namespace std; // 使用命名空间std&#xff0c;这样我们就可以直接使用std中的名字&#xff0c…

设定嵌入式linux系统的用户名和密码

遇到一个问题&#xff0c;板子上电后&#xff0c;串口可以正常输入命令行&#xff0c;而且不需要密码&#xff0c;用户名就是root &#xff0c;因为没有设置密码&#xff0c;但是SSH登录时用户名输入root&#xff0c;密码直接敲回车键也就是不输入密码竟然是错误的&#xff0c;…

一文带你入门Nacos:从安装到实例分析

目录 一、安装和配置 1.1 下载安装包 1.2 解压 1.3 端口配置 1.4 启动 1.5 访问 二、服务注册到nacos 2.1 引入依赖 2.2 配置nacos地址 2.3 重启 三、服务分级存储模型 3.1 给user-service配置集群 3.2 同集群优先的负载均衡 1&#xff09;给order-service配…