十分钟带你深入理解V8引擎的事件循环机制

前言

JavaScript作为一种单线程、非阻塞的语言,其执行模型是通过事件循环机制来实现的。所以理解JavaScript的运行原理,事件循环机制是一个关键的概念。

V8引擎作为JavaScript的主要运行时环境之一,其事件循环机制的实现细节也值得我们深入探讨。

正文

在了解事件循环机制之前,我们得补充一点前置知识

我们先来了解什么是同步代码异步代码

微任务宏任务又是什么呢?

1. 同步代码和异步代码:

  • 同步代码: 同步代码是按照代码的先后顺序依次执行的,一个任务必须等待前一个任务完成后才能执行。
  • 异步代码: 异步代码允许一个任务在执行的同时,其他任务也可以继续执行。当一个异步任务完成时,系统会通知,从而不会阻塞整个程序的执行。

2. 微任务和宏任务:

  • 微任务: 微任务是一种特殊的异步任务,它在当前代码块执行完成后立即执行,优先级比宏任务高。常见的微任务包括 Promise 的回调函数、MutationObserver 等。
  • 宏任务: 宏任务是常规的异步任务,它在当前代码块执行完成后执行,优先级比微任务低。常见的宏任务包括 setTimeout、setInterval、setImmedate()、I/O操作等。

image.png

既然我们已经知道了这些知识了

那我们开始讲解事件循环机制(Event Loop)的执行流程了

事件循环机制(Event Loop)的执行流程分为五步

  1. 执行同步代码(属于宏任务)
  2. 同步执行完毕后,检查是否有异步需要执行
  3. 如果有,则执行微任务队列中的所有任务
  4. 微任务队列执行完毕后,如果有需要就会渲染页面
  5. 执行异步宏任务,也是开启下一次时间循环

接下来我们通过代码去分析这五步流程

image.png

let a = 1;
console.log(a); // 1

setTimeout(() => {
  console.log(++a); 
}, 1000);

console.log(a); // 1
  1. 首先声明并赋值变量 a = 1
  2. 紧接着打印出 a 的值 1,其中像这些赋值操作都是同步代码。
  3. 然后遇到 setTimeout 函数,这是一个异步操作。V8 引擎会将这个异步任务放入宏任务队列中,等待适当的时机再执行。同时,主线程会继续执行下面的同步代码。
  4. 接下来打印出 a 的值 1。这时 a 的值还没有被修改。
  5. 1 秒钟后,setTimeout 的回调函数被执行。此时 a 的值为 1,打印出 1,然后 a 自增为 2

难度提升咯
image.png

console.log(1);
new Promise((resolve, reject) => {
  console.log(2);
  resolve();
})
  .then(() => {
    console.log(3);
  })
  .then(() => {
    console.log(4);
  });
setTimeout(() => {
  console.log(5);
});
console.log(6); // 12645
  1. 首先打印出 1
  2. 接下来创建一个新的 Promise 对象,在 Promise 构造函数中立即打印出 2
  3. Promise 的构造函数中 resolve() 被调用,这个 Promise 对象的状态变为 resolved。
  4. 然后 .then() 方法被调用,会将其中的回调函数作为微任务加入到微任务队列中。
  5. 紧接着又调用了一次 .then(),同样会将其回调函数加入微任务队列。
  6. 之后遇到了 setTimeout,它会将回调函数加入到宏任务队列中。
  7. 最后打印出 6

难度再升级

image.png

console.log(1);
new Promise((resolve, reject) => {
  console.log(2);
  resolve();
}).then(() => {
  console.log(3);
  setTimeout(() => {
    console.log(4);
  }, 0);
});
setTimeout(() => {
  console.log(5);
  setTimeout(() => {
    console.log(6);
  }, 0);
}, 0);
console.log(7); // 1273546
  1. 首先打印出 1
  2. 接下来创建一个新的 Promise 对象,在 Promise 构造函数中立即打印出 2
  3. Promise 的 resolve() 被调用,这个 Promise 对象的状态变为 resolved。
  4. 然后 .then() 方法被调用,会将其中的回调函数作为微任务加入到微任务队列中。
  5. .then() 回调函数中,首先打印出 3
  6. 然后遇到了 setTimeout,它会将回调函数加入到宏任务队列中,并设置延迟时间为 0 毫秒。
  7. 接下来遇到了另一个 setTimeout,它也会将回调函数加入到宏任务队列中,并设置延迟时间为 0 毫秒。
  8. 最后打印出 7

最后的考验,明白这个,你就完全理解了V8引擎的事件循环机制了
这里的细节之处就是await会将后续代码放入微任务队列中

image.png

console.log("script start");

async function async1() {
  await async2(); 
  console.log("async1 end");
}
async function async2() {
  console.log("async2 end");
}
async1();
setTimeout(function () {
  console.log("setTimeout");
}, 0);
new Promise(function (resolve, reject) {
  console.log("promise");
  resolve();
})
  .then(() => {
    console.log("then1");
  })
  .then(() => {
    console.log("then2");
  });
console.log("script end");
  1. 首先打印 "script start"
  2. 调用 async1() 函数,在这个函数中遇到 await async2()
  3. async2() 函数被执行,立即打印 "async2 end"
  4. 回到 async1() 函数,由于 await 的存在,async1() 函数会暂停执行,直到 async2() 完成,并且await会将后续代码放入微任务队列中。
  5. 然后创建了一个 Promise 对象,立即打印 "promise"
  6. 接下来打印 "script end"
  7. 由于 async1() 函数之前被暂停了,现在它可以继续执行,打印 "async1 end"
  8. 然后执行 Promise 的 .then() 回调,打印 "then1""then2"
  9. 最后执行 setTimeout 的回调,打印 "setTimeout"

总结

本文深入讲解了V8引擎的事件循环机制,相信看到这里的你一定会有收获的!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【ElasticSearch】windows server 2019安装ES8.9.1 + kibana8.9.1 + IK分词器

目录 准备工作 ES Kibana IK 安装 es es访问测试 将es安装为系统服务 Kibana 配置es 运行kibana 访问测试 IK 补充 准备工作 ES8.9.1 kibana8.9.1 IK的版本最好要对应上!!! ES es8.9.1: https://artifa…

Eureka到Nacos迁移实战:解决配置冲突与启动异常

问题:Eureka到Nacos迁移实战:解决配置冲突与启动异常 在进行微服务架构升级,特别是注册中心从Eureka转向Nacos的过程中,我遇到了一个典型的技术挑战。目标是为了减少因配置变更导致的服务重启频率,我决定拥抱Nacos以其…

Mybatis --- 动态SQL 和数据库连接池

文章目录 一、什么是动态SQL 重要性二、动态SQL的编写 ---注解三、动态SQL的编写 ---xml3.1 增加场景 if标签3.2 处理代码块内容 --- trim 标签3.3 查询场景 where标签3.4 更新场景 set标签3.5 删除场景 <foreach> 循环标签3.6 include、sql标签 代码重复度问题 四、数据…

关于docker无法正常下载镜像的问题

文章目录 之前还可以正常下载镜像&#xff0c;但是一段时间之后就无法下载了&#xff0c;猜测可能是政治原因&#xff0c;无法连接到国外服务器&#xff0c;所以我设置了阿里云的镜像加速器。 配置方法如下&#xff1a; 前往阿里云&#xff08;https://help.aliyun.com/zh/acr/…

电力系统中臭氧传感器的应用

在电力系统中&#xff0c;设备的安全运行和环境的保护是两大核心任务。为了实现这一目标&#xff0c;各种传感器技术被广泛应用于电力系统的各个环节。其中&#xff0c;臭氧传感器以其独特的监测功能&#xff0c;在电力系统的绝缘状态监测、空气质量监测、环保监测以及预警与故…

蓝桥杯软件测试第十五届蓝桥杯模拟赛1期题目解析

PS 需要第十五界蓝桥杯模拟赛1期功能测试模板、单元测试被测代码、自动化测试被测代码请加&#x1f427;:1940787338 备注&#xff1a;15界蓝桥杯省赛软件测试模拟赛1期 题目1 功能测试用例1&#xff08;测试用例&#xff09;&#xff08;15分&#xff09; 【前期准备】 按步…

AI图书推荐:用ChatGPT按需DIY定制来赚钱

《用ChatGPT按需DIY定制来赚钱》ChatGPT Print Money Method &#xff0c;作者是Cindy Donovan 。 下面是图书概要&#xff1a; ### 第一章&#xff1a;什么是按需印刷以及ChatGPT如何使其变得简单易行&#xff1f; 本章介绍了按需印刷的商业模式&#xff0c;即仅在收到订单时…

Python私教张大鹏 Vue3整合AntDesignVue之Form 表单

何时使用 用于创建一个实体或收集信息。 需要对输入的数据类型进行校验时。 表单 我们为 form 提供了以下三种排列方式&#xff1a; 水平排列&#xff1a;标签和表单控件水平排列&#xff1b;&#xff08;默认&#xff09; 垂直排列&#xff1a;标签和表单控件上下垂直排列…

量化、剪枝、蒸馏,这些大模型黑话到底说了些啥?

扎克伯格说&#xff0c;Llama3-8B还是太大了&#xff0c;不适合放到手机中&#xff0c;有什么办法&#xff1f; 量化、剪枝、蒸馏&#xff0c;如果你经常关注大语言模型&#xff0c;一定会看到这几个词&#xff0c;单看这几个字&#xff0c;我们很难理解它们都干了些什么&…

笔记99:OSQP 求解器示例代码

注1&#xff1a;以下代码是 OSQP 的官方文档提供的示例&#xff0c;我加上了详细的注释&#xff1b; 注2&#xff1a;OSQP 库仅支持C语言&#xff0c;不支持C&#xff0c;所以下面的示例代码使用的是C语言&#xff1b;但是 OSQP 求解库提供了针对C的接口 OSQP-EIGEN&#xff1…

DockerCompose+Jenkins+Pipeline流水线打包Vue项目(解压安装配置Node)入门

场景 DockerComposeJenkinsPipeline流水线打包SpringBoot项目(解压安装配置JDK、Maven等)入门&#xff1a; DockerComposeJenkinsPipeline流水线打包SpringBoot项目(解压安装配置JDK、Maven等)入门-CSDN博客 以上使用流水线配置和打包springboot后台项目&#xff0c;如果要使…

redis未授权getshell整合利用

一、redis环境搭建 Redis下载地址&#xff1a;http://download.redis.io/releases/redis-4.0.2.tar.gz 1.靶机安装redis-centos7 第一步&#xff1a;下载wget yum -y install wget 第二步&#xff1a;下载redis wget http://download.redis.io/redis-stable.tar.gz 第三步&a…

Ajax的应用

1. Ajax Ajax是Asynchronous Javascript And XML&#xff08;异步JavaScript和XML&#xff09;的缩写。 Ajax技术描述了使用脚本操纵HTTP和Web服务器进行数据交换&#xff0c;在页面不刷新的情况下&#xff0c;实现页面的局部更新。 重点&#xff1a; Ajax 是一种在无需重新加…

界面组件DevExpress Office File API - 如何用OpenAI增强文档可访问性(二)

DevExpress Office File API是一个专为C#, VB.NET 和 ASP.NET等开发人员提供的非可视化.NET库。有了这个库&#xff0c;不用安装Microsoft Office&#xff0c;就可以完全自动处理Excel、Word等文档。开发人员使用一个非常易于操作的API就可以生成XLS, XLSx, DOC, DOCx, RTF, CS…

深度学习500问——Chapter10:迁移学习(4)

文章目录 11.3.8 流形学习方法 11.3.9 什么是finetune 11.3.10 finetune为什么有效 11.3.11 什么是网络自适应 11.3.12 GAN在迁移学习中的应用 参考文献 11.3.8 流形学习方法 什么是流行学习&#xff1f; 流行学习自从2000年在Science上被提出来以后&#xff0c;就成为了机器…

webstorm yarn环境配置

1. 安装nodejs https://nodejs.cn/download/ 2. 安装npm npm i yarn -g3.下载并安装webstorm https://www.jetbrains.com/webstorm/ 4. 打开settings确认node和yarn的配置正确5. 打开项目更新包 yarn install

IntelliJ IDEA 用maven创建web项目

前言 已经安装并配置好Tomcat。具体步骤&#xff1a;Tomcat安装及环境变量配置(一看就会)-CSDN博客​编辑https://blog.csdn.net/longyongyyds/article/details/135825647 具体步骤 1.新建一个maven项目 2&#xff0c;配置好tomcat服务器 3.运行测试一下 maven教程&#xf…

Redisson原理解析

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

2024大交通场景空间策展洞察报告

来源&#xff1a;邻汇吧&万一商管 近期历史回顾&#xff1a; 2024国内工商业储能市场研究报告.pdf 2023幸福企业白皮书.pdf 2024年欧亚地区移动经济报告.pdf 内容供应链变革 2023人工智能与首席营销官&#xff08;CMO&#xff09; AI科技对PC产业的影响.pdf 金融业数据应用…

Vitis HLS 学习笔记--Vitis Accelerated Libraries介绍

1. 简介 Vitis Accelerated Libraries&#xff0c;包含很多现成的库&#xff0c;这些库都是开源的&#xff0c;也就是说代码是公开的&#xff0c;而且已经优化过&#xff0c;可以让程序运行得更快。你不需要改变太多你的代码&#xff0c;就能让你的程序速度提升。 这些库有很…