JS事件循环机制event loop宏任务微任务原理解析

接下来我会详细讲解一下JS事件循环机制(event loop)、宏任务和微任务的原理,以及该如何理解它们之间的关系。

1. 事件循环机制(event loop)的原理

在JavaScript中,事件循环机制定义了一种代码执行模型,可以控制代码在何时执行。事件循环机制主要分为以下两个部分:

  • 执行栈(Execution Context Stack)
  • 任务队列(Task Queue)

我们可以将代码执行栈看做是一个存储函数执行上下文的地方,每当调用一个函数,就会将其对应的执行上下文压入栈中,并等待执行完毕。而任务队列则存储了当前已经准备好的任务,它们会在其他任务执行完成后,由事件循环机制取出来执行。

当JavaScript引擎首次遇到全局代码时,它会创建一个全局执行上下文,并将它压入执行栈中。而后续的任何JavaScript代码执行,都会通过执行栈中不断地加入和弹出执行上下文来实现。

在事件循环机制中,除了主线程(执行栈)之外,还有一个任务队列(Task Queue)。任务队列会接受异步任务并按照顺序存储起来,这些异步任务又分为两种类型:宏任务和微任务。

2. 宏任务和微任务的原理

宏任务

宏任务指的是那些需要进入事件队列与其他事件竞争执行权的代码块,例如:load事件、定时器事件(setTimeout、setInterval)等。

当执行栈为空时,事件循环机制会从宏任务队列中取出任务来执行,执行时期间可能会导致执行栈中再次压入执行上下文,也可能会影响变量的状态。当执行过程完成后,事件循环机制会在检查当前宏任务队列和微任务队列是否为空的情况下,执行位于队列头部的任务。

示例:

console.log('1');
setTimeout(() => {
  console.log('2');
}, 0);
console.log('3');

执行结果:

1
3
2

很显然,setTimeout函数会被放入宏任务队列中,而由于发生了异步调用,因此不会阻止主线程的执行。最后,任务队列中的宏任务被执行,并打印出“2”

微任务

微任务指的是在JavaScript引擎执行栈为空并且调用栈中的所有函数都已经返回的情况下,需要执行的代码块,例如Promise回调函数、MutationObserver监听等。

当执行栈为空时,事件循环机制会优先处理微任务队列中的任务,如果没有微任务需要处理,则会切换到宏任务队列中的事件。

示例:

console.log(1);

setTimeout(() => {
  console.log(2);
});

new Promise(resolve => {
  console.log(3);
  resolve(4);
}).then((value) => {
  console.log(value);
});

console.log(5);

执行结果:

1
3
5
4
2

在以上的示例中,Promise回调函数会被放入微任务队列中,而由于异步调用发生在“35”行代码之后,因此在主线程执行完之前,Promise回调函数就已经被放入了微任务队列中,事件循环机制就会在执行完成主线程中的执行栈之后,优先执行Promise回调函数这个微任务。最终,任务队列中的宏任务被执行,并打印出“2”。

结语

以上就是JS事件循环机制和宏任务微任务的完整攻略。通过对比分析,我们可以得出一条结论:无论是宏任务还是微任务,事件循环机制都会按照队列中的顺序依次执行它们。根据实际的业务场景,可以将需要执行的代码加入到微任务或宏任务队列中,帮助JavaScript引擎更好地控制代码的执行时机。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JS事件循环机制event loop宏任务微任务原理解析 - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • JSP建立错误页页面并自动跳转

    建立错误页页面并自动跳转的过程如下: 1. 创建错误页页面 在 JSP 项目中,我们可以通过创建一个名为 error.jsp 的 JSP 页面作为错误页页面。在 error.jsp 中,我们可以通过使用 JSP 的内置对象 exception 和 page 变量来输出错误信息,并提供用户回到网站主页的链接,如下所示: <%@ page language…

    JavaScript 2023年5月27日
    00
  • 实例教程 纯CSS3打造非常炫的加载动画效果

    通过本实例教程,我们将使用纯 CSS3 技术来构建一些极其酷炫的网站加载动画效果。在本教程中,我们将学习如何使用 CSS3 的关键帧动画和过渡方法来创建许多有趣的动画。 1. 准备工作 在开始编写动画之前,需要先准备好一个 HTML 文件。你可以在文件中添加一些模拟加载过程的标签来测试你的动画。一些可以用于这个目的的标签是:div,span,img 等。 2…

    JavaScript 2023年6月11日
    00
  • Javascript中暂停功能的实现代码

    要实现Javascript中的暂停功能,可以采用以下几种方法: 方法一:使用setTimeout 使用setTimeout函数可以实现暂停功能,具体实现方式如下: function sleep(milliseconds) { return new Promise(resolve => setTimeout(resolve, milliseconds))…

    JavaScript 2023年6月10日
    00
  • 用正则获取指定路径文件的名称

    获取指定路径下文件的名称通常会用到正则表达式,下面是获取指定路径下某类文件名的完整攻略: 步骤一:指定路径 在使用正则表达式之前,需要指定要查找的文件所在的路径。可以使用Python内置的os库函数,比如os.getcwd()获取当前路径,或者os.chdir()改变当前目录路径。 示例代码: # 获取当前路径 import os path = os.get…

    JavaScript 2023年6月10日
    00
  • javascript利用正则快速找出两个字符串的不同字符

    JavaScript利用正则表达式可以快速找出两个字符串的不同字符,具体的步骤如下: 首先将两个字符串的长度进行比较,以较短的字符串长度为基准。 对两个字符串进行遍历,比较对应字符是否相等,如果不相等,就将差异字符记录下来。 利用正则表达式去重,即将记录下来的差异字符进行去重操作。 下面是两个示例说明: 示例1: function findDifferent…

    JavaScript 2023年5月28日
    00
  • 基于Javascript实现文件实时加载进度的方法

    实现文件实时加载进度的方法本质上就是通过监听HTTP请求,统计请求发起时和请求完成时的时间,并通过计算来得出百分比进度。下面是实现文件实时加载进度的详细教程: 准备工作 首先,在页面中引入jQuery: <script src="//code.jquery.com/jquery-3.3.1.min.js"></scrip…

    JavaScript 2023年5月27日
    00
  • Javascript 各浏览器的 Javascript 效率对比

    首先,为了详细讲解JavaScript各浏览器的效率对比,我们需要先了解一下什么是JavaScript。简单地说,JavaScript是一种通过浏览器来运行的脚本语言,主要用于网页的动态交互和视觉效果制作。 在JavaScript的效率对比方面,一般使用各个浏览器所支持的benchmark测试来进行比较。benchmark测试是一个基准测试套件,它被用来测量…

    JavaScript 2023年5月19日
    00
  • vue-element的select下拉框赋值实例

    下面是针对vue-element的select下拉框赋值实例的详细攻略: 1. 安装vue-element-ui 首先,在vue项目中安装vue-element-ui库。可以运行以下命令来安装: npm install element-ui -S 接着,在main.js文件中引入并使用vue-element-ui插件: import Vue from ‘vu…

    JavaScript 2023年6月10日
    00
合作推广
合作推广
分享本页
返回顶部