JS事件循环-微任务-宏任务(原理讲解+面试题分析)

JS事件循环-微任务-宏任务

在JS中,事件循环是一种非常重要的机制。通过事件循环,我们可以更好地实现代码的异步执行。了解JS事件循环的机制,也是在前端开发中非常必要的一项知识。

事件循环机制

事件循环机制是指JS引擎处理JS代码的一种机制。简单来说,JS引擎在执行JS代码时,会按照特定的顺序去处理事件,而这个顺序就是事件循环。与此同时,JS引擎还会把这些事件分成两类:微任务和宏任务。

微任务和宏任务

微任务

微任务是一种比较“轻量级”的事件,它的执行时间一般比较短,并且微任务的执行顺序也比较靠前,即在下一个事件循环执行之前执行。微任务包括以下几种:

  • Promise
  • process.nextTick (Node.js)
  • MutationObserver (浏览器)

宏任务

宏任务是一种比较“重量级”的事件,它的执行时间可能会比较长,并且宏任务的执行顺序也比较靠后,即在下一个事件循环执行之后执行。宏任务包括以下几种:

  • setTimeout
  • setInterval
  • setImmediate (Node.js)
  • requestAnimationFrame (浏览器)
  • I/O (Node.js)

事件循环流程

事件循环的流程大致分为以下几步:

  1. 首先,JS引擎会从宏任务队列中取出一个任务执行,如果宏任务队列为空,则会执行微任务队列中的所有任务。
  2. 接着,JS引擎会处理微任务队列中的所有任务,并且把新产生的微任务加入微任务队列中。
  3. 然后,JS引擎会处理宏任务队列中的下一个任务,如果宏任务队列中还有任务,则重复第1~3步,直到宏任务队列为空为止。

示例

示例一

console.log('start')

setTimeout(() => {
  console.log('timer1')

  Promise.resolve().then(() => {
    console.log('promise1')
  })
}, 0)

setTimeout(() => {
  console.log('timer2')

  Promise.resolve().then(() => {
    console.log('promise2')
  })
}, 0)

Promise.resolve().then(() => {
  console.log('promise3')
})

console.log('end')

输出结果为:

start
end
promise3
timer1
promise1
timer2
promise2

代码执行过程分析:

  1. 执行console.log('start')
  2. 执行第1个setTimeout(),将timer1任务放入宏任务队列
  3. 执行第2个setTimeout(),将timer2任务放入宏任务队列
  4. 执行Promise.resolve().then(() => { console.log('promise3') }),将promise3任务放入微任务队列
  5. 执行console.log('end')
  6. 触发下一轮事件循环,第1个宏任务队列中取出timer1任务执行,将promise1任务放入微任务队列
  7. 微任务队列中取出promise3任务执行
  8. 触发下一轮事件循环,第1个宏任务队列中没有任务,执行微任务队列中的promise1任务并将promise2任务放入微任务队列
  9. 微任务队列中取出promise2任务执行

示例二

console.log('start')

setTimeout(() => {
  console.log('timer1')

  Promise.resolve().then(() => {
    console.log('promise1')
  })
}, 0)

Promise.resolve().then(() => {
  console.log('promise2')
})

console.log('end')

输出结果为:

start
end
promise2
timer1
promise1

代码执行过程分析:

  1. 执行console.log('start')
  2. 执行setTimeout(),将timer1任务放入宏任务队列
  3. 执行Promise.resolve().then(() => { console.log('promise2') }),将promise2任务放入微任务队列
  4. 执行console.log('end')
  5. 触发下一轮事件循环,第1个宏任务队列中取出timer1任务执行,将promise1任务放入微任务队列
  6. 微任务队列中取出promise2任务执行
  7. 微任务队列中取出promise1任务执行

面试题分析

以下是一道经典的面试题:

console.log('1')

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

Promise.resolve().then(() => {
  console.log('3')
})

console.log('4')

输出结果是: 1 4 3 2

这个面试题考察了对事件循环机制的掌握。我们可以根据上述的分析过程,来解释这个题目的输出结果。

  1. 执行console.log('1')
  2. 执行setTimeout(),将2任务放入宏任务队列
  3. 执行Promise.resolve().then(() => { console.log('3') }),将3任务放入微任务队列
  4. 执行console.log('4')
  5. 触发下一轮事件循环,第1个宏任务队列中取出2任务执行
  6. 微任务队列中取出3任务执行

因此,输出结果为:1 4 3 2

综上所述,我们必须掌握JS事件循环机制以及微任务和宏任务的区别,这是学习JS中异步编程非常重要的一步。在面试中,对于事件循环机制和异步编程的问题,也是非常常见的。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JS事件循环-微任务-宏任务(原理讲解+面试题分析) - Python技术站

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

相关文章

  • Nodejs Post请求报socket hang up错误的解决办法

    下面我将为你详细讲解“Nodejs Post请求报socket hang up错误的解决办法”。 问题分析 当使用Nodejs发送Post请求时,可能会出现“socket hang up”错误,造成请求失败。这个错误通常发生在以下情况之一: 请求超时,服务器没有及时响应。 请求的数据量比较大,Nodejs默认的请求体大小限制被超出。 请求时发生了错误,导致请…

    node js 2023年6月8日
    00
  • node命令行工具之实现项目工程自动初始化的标准流程

    下面是实现项目工程自动初始化的标准流程: 1. 创建项目 在命令行中创建项目文件夹,并在其内部添加项目 package.json 文件。 mkdir auto-init-project cd auto-init-project npm init -y 2. 创建node cli工具 使用以下命令生成一个全局安装的包,该包将成为node命令行工具。 npm i…

    node js 2023年6月8日
    00
  • nodeJs实现基于连接池连接mysql的方法示例

    接下来我会为您详细讲解“Node.js实现基于连接池连接MySql的方法示例”的攻略。 步骤一:安装mysql模块 在开始使用Node.js连接MySQL数据库之前,需要先安装Node.js的MySQL模块。可以使用npm包管理器进行安装,具体命令如下: npm install mysql –save 安装完成后,可以使用以下代码测试是否成功安装: con…

    node js 2023年6月9日
    00
  • Node.js文件系统fs扩展fs-extra说明

    Node.js 是一个非常流行的 JavaScript 运行环境,它提供了多种操作文件系统的方式。但是,官方的文件系统模块(fs)并不够完善,可能需要使用 fs-extra 这个第三方扩展库。fs-extra 模块为 Node.js 应用程序提供了更好的文件处理方法和 API。 什么是 fs-extra fs-extra 是一个基于 Node.js 文件系统…

    node js 2023年6月8日
    00
  • Node.js 使用递归实现遍历文件夹中所有文件

    下面是如何使用 Node.js 递归实现遍历文件夹中所有文件的完整攻略。 需要用到的 Node.js 模块 首先,我们需要 Node.js 来处理文件系统的操作,需要两个核心模块: fs模块 :用于访问文件系统。 path 模块:用于处理文件路径的工具。 因此,我们在开始之前需要先引入这两个模块。 const fs = require(‘fs’); cons…

    node js 2023年6月8日
    00
  • 详解Node.js中path模块的resolve()和join()方法的区别

    当我们需要在Node.js中操作文件路径时,常用的模块是path模块。path模块提供了一些方法来处理路径问题,其中最常用的就是resolve()和join()方法。这两个方法可以帮助我们创建正确的路径,但是它们使用的方式不同,下面我们对它们进行详细讲解。 resolve()方法 resolve()方法可以将相对路径转换为绝对路径,并解析路径中的.和..。这…

    node js 2023年6月8日
    00
  • 利用Node转换Excel成JSON的详细步骤

    利用Node.js转换Excel文件为JSON格式的过程大致可分为以下几步: 安装依赖库:首先我们需要安装一些必要的Node.js依赖库,比如xlsx和fs,这些库可以通过NPM(Node Package Manager)进行安装 npm install –save xlsx fs 读取Excel文件:使用xlsx库可以读取Excel文件并将其转换为JSO…

    node js 2023年6月8日
    00
  • 教你如何在Node.js中使用jQuery

    让我详细讲解一下如何在 Node.js 中使用 jQuery。 Step 1:安装 jQuery 在 Node.js 中使用 jQuery,第一步是需要安装 jQuery 库。可以通过 npm 进行安装,打开命令行窗口,输入以下命令进行安装: npm install jquery Step 2:创建实例 在安装完 jQuery 后,就可以在 Node.js …

    node js 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部