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

yizhihongxing

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日

相关文章

  • node+koa2+mysql+bootstrap搭建一个前端论坛

    这里给出一个基于node+koa2+mysql+bootstrap搭建一个前端论坛的完整攻略,包括环境配置、项目结构、代码实现等。这个项目将会实现以下功能: 用户注册和登录 发布和删除文章,并支持文章评论和点赞功能 收藏文章和个人中心页面 环境配置 首先,需要安装node.js和mysql数据库。在安装完成后,可以使用npm安装koa2的脚手架工具koa-g…

    node js 2023年6月8日
    00
  • Vue.js中v-show和v-if指令的用法介绍

    当我们使用Vue.js开发项目的时候,经常会用到v-show和v-if这两个指令。这两个指令都是用于控制Vue.js模板中元素的显示和隐藏。但是,这两个指令的使用场景并不完全相同。接下来我们将详细介绍v-show和v-if指令的用法。 v-show指令的用法 v-show指令用于控制Vue.js模板中元素的显示和隐藏,与普通的CSS属性display:non…

    node js 2023年6月9日
    00
  • puppeteer库入门初探

    Puppeteer库入门初探 Puppeteer是一个基于Node.js的浏览器自动化库,它提供了一套高级API,用于控制Chrome或Chromium以及执行常见的任务,如生成屏幕截图、生成PDF、表单自动提交、网页爬虫等。 安装Puppeteer Puppeteer可以通过npm进行安装,在终端中输入以下命令: npm install puppeteer…

    node js 2023年6月8日
    00
  • JS中队列和双端队列实现及应用详解

    JS中队列和双端队列实现及应用详解 什么是队列? 队列是指一种线性数据结构,它按照先进先出(FIFO)的原则进行排序。队列只允许在后端(称为tail)进行插入操作,在前端(称为head)进行删除操作。例如,当你在一家银行排队等待服务时,由于先来的人先获得服务的原则,所以你必须在队列中等待,直到你到达前面。当有人从银行窗口出来时,他们排在你的前面的所有人都必须…

    node js 2023年6月8日
    00
  • NodeJS学习笔记之FS文件模块

    下面是关于“NodeJS学习笔记之FS文件模块”的完整攻略: 什么是FS模块? Node.js中的FS模块是用于处理文件系统的核心模块之一。它允许您读取、更新和删除文件,以及创建和读取文件夹。 如何使用FS模块? 在使用FS模块之前,必须先引入该模块。可以使用以下代码实现: const fs = require(‘fs’); 读取文件 你可以使用fs.rea…

    node js 2023年6月8日
    00
  • Node.js的路由、EJS模板引擎、GET和POST请求讲解

    Node.js是一个非常流行的服务器端JavaScript运行环境,它提供了一些核心模块以及众多的第三方模块,可以用于开发各种类型的应用程序,包括Web应用程序。在开发Web应用程序时,有一些核心概念和技术是必须掌握的,包括路由、模板引擎以及HTTP请求处理等。 一、Node.js的路由 在Web应用程序中,路由就是根据请求的URL和HTTP方法(GET、P…

    node js 2023年6月8日
    00
  • Nest.js参数校验和自定义返回数据格式详解

    下面给你分享关于“Nest.js参数校验和自定义返回数据格式详解”的完整攻略。 一、参数校验 在Nest.js中,我们可以使用class-validator实现参数校验。需要在controller中使用Dto来对每个请求进行参数校验。具体流程如下: 安装class-validator和class-transformer模块,执行如下命令: npm insta…

    node js 2023年6月8日
    00
  • koa-router源码学习小结

    下面是对“koa-router源码学习小结”的完整攻略。 1. 入口文件 “koa-router”模块的入口文件是“index.js”。 const Router = require(‘./lib/router’); function router(opts) { return new Router(opts); } PATTERN_FLAGS.forEac…

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