js之事件循环

JavaScript的事件循环是它的并发模型的核心部分,使得JavaScript能够在单线程中处理异步操作。事件循环允许JavaScript在执行代码时,同时进行非阻塞的I/O操作(如网络请求、文件操作等)。这个概念对于理解如何高效地构建交互式Web应用程序是至关重要的。

事件循环的工作流程

JavaScript运行时环境包含一个待处理消息的队列。每个消息都关联着一个用以处理这个消息的函数。当堆栈(包含当前执行的所有代码)为空时,事件循环会从队列中取出一个消息,然后处理它。这个处理包括调用与消息关联的函数(及其调用堆栈)。这个函数执行完毕后,堆栈空出,事件循环继续处理下一个消息,这个过程持续不断。

宏任务(Macrotask)与微任务(Microtask)

事件循环中的任务可以分成两种:宏任务(如setTimeout、setInterval、I/O操作)和微任务(如Promise.then、MutationObserver)。两者的主要区别在于它们被执行的时机。

宏任务(Macrotask): 每次执行完一个宏任务,都会检查微任务队列是否有任务,如果有,则会先执行微任务队列中的所有任务,然后才会执行下一个宏任务。

微任务(Microtask): 当前任务执行完毕后立即执行的任务。所有微任务执行完毕之后,若存在渲染操作,则会执行渲染操作,然后继续回到宏任务的执行。

事件循环的步骤

  1. 执行全局脚本:加载脚本后,全局脚本开始执行。
  2. 执行宏任务:一旦全局脚本执行完毕,事件循环会从宏任务队列中取出一个任务执行。
  3. 执行微任务:在当前宏任务执行完毕后,会检查微任务队列,如果队列不为空,则执行队列中的所有微任务。这些微任务可能会继续添加新的微任务到微任务队列中。事件循环会一直执行微任务队列中的任务,直到队列清空。
  4. 渲染:完成宏任务和微任务后,渲染界面(如果有必要的话)。
  5. 回到步骤2:继续从宏任务队列中取出下一个任务,重复这个过程。

例子1

console.log('script start');setTimeout(function() {console.log('setTimeout');
}, 0);Promise.resolve().then(function() {console.log('promise1');
}).then(function() {console.log('promise2');
});console.log('script end');

执行顺序:

console.log('script start');
  1. ‘script start’ 打印到控制台。这是同步代码的一部分,所以它首先执行。
setTimeout(function() {console.log('setTimeout');
}, 0);
  1. setTimeout是一个宏任务。尽管延迟是0,但这个setTimeout回调(任务)不会立即执行;它被加入到宏任务队列等待执行。在当前执行栈(包括紧接着执行的微任务)执行完之前,setTimeout的回调不会被执行。
Promise.resolve().then(function() {console.log('promise1');
}).then(function() {console.log('promise2');
});
  1. Promise.resolve()是立即解决的Promise,.then回调(设置的第一个promise1打印操作)被加入到微任务队列,将在当前宏任务的同步任务执行完毕后立即执行。

  2. 第二个.then(即promise2打印操作)也会成为一个微任务,它将在第一个.then执行后被加入到微任务队列。

console.log('script end');
  1. ‘script end’ 打印到控制台。这也是同步代码的一部分,紧随'script start'的打印之后执行。

至此,同步任务执行完毕。事件循环将会查看微任务队列,看是否有任务需要执行;在这种情况下,微任务队列中有两个由Promise产生的任务需要执行:

  1. ‘promise1’ 被打印到控制台。这是第一个微任务。

  2. 由于第一个.then的回调执行完毕,第二个.then的回调(作为微任务)现在执行,‘promise2’ 被打印到控制台作为第二个微任务。

至此,当前宏任务中的所有微任务都已经被执行。事件循环现在回转到宏任务队列,准备执行下一个宏任务:

  1. ‘setTimeout’ 的回调函数现在执行,因为它是在开始时通过setTimeout提交的宏任务。‘setTimeout’ 被打印到控制台。

最终的执行顺序是:

  1. ‘script start’
  2. ‘script end’
  3. ‘promise1’
  4. ‘promise2’
  5. ‘setTimeout’

例子2

console.log('1');setTimeout(function () {console.log('2');process.nextTick(function () {console.log('3');})new Promise(function (resolve) {console.log('4');resolve();}).then(function () {console.log('5')})
})
process.nextTick(function () {console.log('6');
})
new Promise(function (resolve) {console.log('7');resolve();
}).then(function () {console.log('8')
})setTimeout(function () {console.log('9');process.nextTick(function () {console.log('10');})new Promise(function (resolve) {console.log('11');resolve();}).then(function () {console.log('12')})
})

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

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

相关文章

本地模拟发送、接收RabbitMQ数据

文章目录 前言一、相关文章二、相关代码1.模拟的 Channel 类2.接收消息3.模拟推送MQ数据前言 日常开发中,当线上RabbitMQ坏境还没准备好时,可在本地模拟发送、接收消息 一、相关文章 Docker安装RabbitMQ 【SpringCloud】整合RabbitMQ六大模式应用(入门到精通) Spring R…

Spring学习笔记(三)--Spring中的Bean的管理

一、什么是Bean Bean是注册到Spring容器中的Java类,控制反转和依赖注入都是通过Bean实现的,任何一个Java类都可以是一个Bean。Bean由Spring进行管理,可以通过xml文件对bean进行配置和管理。 二、BeanFactory接口和ApplicationContext接口&a…

利用Python实现科学式占卜

一直以来,中式占卜都是基于算命先生手工实现,程序繁琐(往往需要沐浴、计算天时、静心等等流程)。准备工作复杂(通常需要铜钱等道具),计算方法复杂,需要纯手工计算二进制并转换为最终…

2023年12月 Python(六级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,共50分) 第1题 运行以下程序,输出的结果是?( ) class A():def __init__(self,x):self.x=x

手机连接电脑后资源管理器无法识别(识别设备但无法访问文件)

问题描述 小米8刷了pixel experience系统,今天用电脑连接后无法访问手机文件,但是手机选择了usb传输模式为文件传输 解决办法 在设备和打印机页面中右键选择属性 点击改变设置 卸载驱动,注意勾选删除设备的驱动程序软件 卸载后重新连接手机,电脑弹出希望对设备进行什么操作时…

Code-Audit(代码审计)习题记录4-5

4、习题4 题目内容如下&#xff1a; <?php error_reporting(0); show_source(__FILE__); $a $_REQUEST[hello]; eval("var_dump($a);"); 函数解释 $REQUEST — HTTP Request 变量&#xff0c;默认情况下包含了 [$GET]&#xff0c;[$POST] 和 [$COOKIE]的数…

HTML知识点

HTML 【一】HTML简介 【1】什么是HTML HTML是一种用于创建网页结构和内容的超文本标记语言&#xff0c;它是构建网页的基础。为了让浏览器正确渲染页面&#xff0c;我们必须遵循HTML的语法规则。浏览器在解析网页时会将HTML代码转换为可视化的页面&#xff0c;所以我们在浏览…

python接口测试实践:参数化测试、数据驱动测试和断言的使用

在Python接口测试实践中&#xff0c;参数化测试、数据驱动测试和断言是常用的技术手段。 参数化测试 参数化测试是指将测试用例中的某些部分&#xff08;如输入数据或配置&#xff09;作为参数传递给测试函数&#xff0c;以便于复用和减少代码重复。 例如&#xff0c;使用uni…

2024年最新腾讯云轻量4核8G12M服务器CPU内存性价比如何?

4核8G服务器支持多少人同时在线访问&#xff1f;阿腾云的4核8G服务器可以支持20个访客同时访问&#xff0c;关于4核8G服务器承载量并发数qps计算测评&#xff0c;云服务器上运行程序效率不同支持人数在线人数不同&#xff0c;公网带宽也是影响4核8G服务器并发数的一大因素&…

设计模式--组合模式(Composite Pattern)

组合模式(Composite Pattern)是一种结构型设计模式,它允许你将对象组合成树形结构,并且能像使用独立对象一样使用它们。 组合模式主要包含以下几个角色: Component:这是组合中对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理C…

oracle数据库事务的四大特性与隔离级别与游标

数据库事务的四大特性: 这里提到了 ACID 四个特性&#xff0c;分别是&#xff1a; A&#xff08;Atomicity&#xff09;&#xff1a; 原子性&#xff0c;确保事务中的所有操作要么全部执行成功&#xff0c;要么全部不执行&#xff0c;不存在部分执行的情况。 C&#xff08;…

时序分析深入必学的时序模型详细讲解

目录 一、前言 二、时序建模 2.1 反相器 2.2 线性时序模型 2.3 非线性时序模型 三、时序模块 3.1 组合单元 3.2 时序单元 3.3 同步检查&#xff1a;setup和hold 3.4 异步检查&#xff1a;recovery和removal 3.5 脉冲宽度检查Pulse width check 3.6 传输时延 3.7 …

微信小程序配置文件

目录 小程序配置文件 1. 配置文件介绍 2. 全局配置 2.1 pages 2.2 window 2.3 tabBar 3. 页面配置 4. 项目配置文件 5. 支持使用 sass/less 6. sitemap.json 小程序配置文件 1. 配置文件介绍 JSON是一种轻量级的数据格式&#xff0c;常用于前后端数据的交互&#xf…

LDRA Testbed软件静态分析_软件质量度量

系列文章目录 LDRA Testbed软件静态分析_操作指南 LDRA Testbed软件静态分析_自动提取静态分析数据生成文档 LDRA Testbed软件静态分析_Jenkins持续集成_(1)自动进行静态分析的环境搭建 LDRA Testbed软件静态分析_Jenkins持续集成_(2)配置邮件自动发送静态分析结果 LDRA Testb…

python数据类型-集合set

1 集合&#xff08;set&#xff09;的定义 1.1 集合是一个无序且不重复元素的序列&#xff1a; 1&#xff09;无序&#xff1a;存储顺序和添加的顺序不一定相同&#xff0c;不支持索引、切片 2&#xff09;元素不重复&#xff1a;当添加重复元素时&#xff0c;集合会自动去重…

scss导出颜色变量为空对象

scss导出颜色变量为空对象 scss文件 $base-menu-color:#bfcbd9; :export {menuColor: $base-menu-color }页面使用 import variables from "/assets/styles/variables.scss";然后打印发现 console.log(variables) // {} 打印值为空对象此时我们需要将文件名varia…

typescript映射类型

ts映射类型简介 TypeScript中的映射类型&#xff08;Mapped Type&#xff09;是一种高级类型&#xff0c;它允许我们基于现有类型创建新的类型&#xff0c;同时对新类型的每个属性应用一个转换函数。通过使用映射类型&#xff0c;我们可以方便地对对象的属性进行批量操作&…

BeautifulSoup的使用与入门

1. 介绍 BeautifulSoup是用来从HTML、XML文档中提取数据的一个python库&#xff0c;安装如下: pip install beautifulsoup4 它支持多种解析器&#xff0c;包括python标准库、lxml HTML解析器、lxml XML解析器、html5lib等。结合稳定性和速度&#xff0c;这里推荐使用lxml HT…

typescript 索引签名类型

ts索引类型简介 在TypeScript中&#xff0c;索引签名类型&#xff08;Index Signature Type&#xff09;是一种特殊的类型&#xff0c;它定义了对象中键的类型以及相应的值的类型。通过使用索引签名类型&#xff0c;我们可以表示一个对象&#xff0c;该对象的键可以是任意类型…

spring boot Mybatis Plus分页

文章目录 Mybatis Plus自带分页和PageHelper有什么区别&#xff1f;Mybatis Plus整合PageHelper分页 springboot自定义拦截器获取分页参数spring boot下配置mybatis-plus分页插件单表分页查询自定义sql分页查询PageHelper 参考 Mybatis Plus自带分页和PageHelper有什么区别&…