.宏任务(macrotask )和微任务(microtask )

macrotask 和 microtask 表示异步任务的两种分类。

在挂起任务时,JS 引擎会将所有任务按照类别分到这两个队列中,首先在 macrotask 的队列(这个队列也被叫做 task queue)中取出第一个任务,执行完毕后取出 microtask 队列中的所有任务顺序执行;之后再取 macrotask 任务,周而复始,直至两个队列的任务都取完。

掘金上面盗张图记录一下

宏任务和微任务之间的关系

先看个例子

  1. setTimeout(() => {
  2. //执行后 回调一个宏事件
  3. console.log('内层宏事件3')
  4. }, 0)
  5. console.log('外层宏事件1');
  6.  
  7. new Promise((resolve) => {
  8. console.log('外层宏事件2');
  9. resolve()
  10. }).then(() => {
  11. console.log('微事件1');
  12. }).then(()=>{
  13. console.log('微事件2')
  14. })

我们看看打印结果

  1. 外层宏事件1
  2. 外层宏事件2
  3. 微事件1
  4. 微事件2
  5. 内层宏事件3

• 首先浏览器执行js进入第一个宏任务进入主线程, 遇到 setTimeout  分发到宏任务Event Queue中

• 遇到 console.log() 直接执行 输出 外层宏事件1

• 遇到 Promise, new Promise 直接执行 输出 外层宏事件2

• 执行then 被分发到微任务Event Queue中

•第一轮宏任务执行结束,开始执行微任务 打印 '微事件1' '微事件2'

•第一轮微任务执行完毕,执行第二轮宏事件,打印setTimeout里面内容'内层宏事件3'

宏任务

 

# 浏览器 Node
setTimeout
setInterval
setImmediate x
requestAnimationFrame x

微任务

# 浏览器 Node
process.nextTick x
MutationObserver x
Promise.then catch finally

这个例子看懂基本js执行机制就理解了

  1. //主线程直接执行
  2. console.log('1');
  3. //丢到宏事件队列中
  4. setTimeout(function() {
  5. console.log('2');
  6. process.nextTick(function() {
  7. console.log('3');
  8. })
  9. new Promise(function(resolve) {
  10. console.log('4');
  11. resolve();
  12. }).then(function() {
  13. console.log('5')
  14. })
  15. })
  16. //微事件1
  17. process.nextTick(function() {
  18. console.log('6');
  19. })
  20. //主线程直接执行
  21. new Promise(function(resolve) {
  22. console.log('7');
  23. resolve();
  24. }).then(function() {
  25. //微事件2
  26. console.log('8')
  27. })
  28. //丢到宏事件队列中
  29. setTimeout(function() {
  30. console.log('9');
  31. process.nextTick(function() {
  32. console.log('10');
  33. })
  34. new Promise(function(resolve) {
  35. console.log('11');
  36. resolve();
  37. }).then(function() {
  38. console.log('12')
  39. })
  40. })

• 首先浏览器执行js进入第一个宏任务进入主线程, 直接打印console.log('1')

• 遇到 setTimeout  分发到宏任务Event Queue中

• 遇到 process.nextTick 丢到微任务Event Queue中

• 遇到 Promise, new Promise 直接执行 输出 console.log('7');

• 执行then 被分发到微任务Event Queue中

•第一轮宏任务执行结束,开始执行微任务 打印 6,8

•第一轮微任务执行完毕,执行第二轮宏事件,执行setTimeout

•先执行主线程宏任务,在执行微任务,打印'2,4,3,5'

•在执行第二个setTimeout,同理打印 ‘9,11,10,12’

•整段代码,共进行了三次事件循环,完整的输出为1,7,6,8,2,4,3,5,9,11,10,12。

以上是在浏览器环境下执行的数据,只作为宏任务和微任务的分析,我在node环境下测试打印出来的顺序为:1,7,6,8,2,4,9,11,3,10,5,12。node环境执行结果和浏览器执行结果不一致的原因是:浏览器的Event loop是在HTML5中定义的规范,而node中则由libuv库实现。libuv库流程大体分为6个阶段:timers,I/O callbacks,idle、prepare,poll,check,close callbacks,和浏览器的microtask,macrotask那一套有区别。

参考文档 https://juejin.im/post/59e85eebf265da430d571f89

    http://www.cnblogs.com/jiasm/p/9482443.html

  

//主线程直接执行
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')
})
})
//微事件1
process.nextTick(function() {
console.log('6');
})
//主线程直接执行
new Promise(function(resolve) {
console.log('7');
resolve();
}).then(function() {
//微事件2
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')
})
})

js 宏任务和微任务的更多相关文章

  1. js的事件循环机制:同步与异步任务(setTimeout,setInterval)宏任务,微任务(Promise,process.nextTick)

    javascript是单线程,一切javascript版的"多线程"都是用单线程模拟出来的,通过事件循环(event loop)实现的异步. javascript事件循环 事件循环 ...

  2. js中的宏任务与微任务

    如果你已经知道了js中存在宏任务和微任务,那么你一定已经了解过promise了.因为在js中promise是微任务的一个入口. 先来看一道题: setTimeout(function(){ conso ...

  3. 10分钟了解js的宏任务和微任务

    熟悉宏任务和微任务以及js(nodejs)事件循环机制,在写业务代码还是自己写库,或者看源码都是那么重要 看了部分文档,自己总结和实践了一下 js中同步任务.宏任务和微任务介绍 同步任务: 普通任务 ...

  4. JS中EventLoop、宏任务与微任务的个人理解

    为什么要EventLoop? JS 作为浏览器脚本语言,为了避免复杂的同步问题(例如用户操作事件以及操作DOM),这就决定了被设计成单线程语言,而且也将会一直保持是单线程的.而在单线程中若是遇到了耗时 ...

  5. 浏览器端时间循环与nodejs端时间循环的不同之处(宏任务与微任务)

    浏览器端与node端都有宏任务与微任务的概念.字面意思上看宏任务就是耗时间比较长的任务,而微任务是耗时短的任务. 在浏览器端,宏任务包括setTimeout,setInterval,微任务则包括Pro ...

  6. 宏任务、微任务与Event Loop

    说到宏任务和微任务,我们就不得不提 Event Loop 了 JS的本质是单线: 1. 一般来说,非阻塞性的任务采取同步的方式,直接在主线程的执行栈完成. 2. 一般来说,阻塞性的任务都会采用异步来执 ...

  7. JavaScript的事件队列(Event Queue)---宏任务和微任务

    前言 在写代码的时候经常思考一个问题,到底是那个函数先执行,本身JavaScript是一门单线程的语言,意思就是按照顺序执行.但是加入一些setTimeout和promise的函数来又实现了异步操作, ...

  8. Event Loop、 宏任务和微任务

    本文将介绍我自己对JS Event Loop 和 宏任务.微任务的理解. 二话不说先上图: 接下来将会针对此图讲解什么是Event Loop 什么事宏任务和微任务(其实聪明的你们通过图大体也能了解的是 ...

  9. 一道题理解setTimeout,Promise,async/await以及宏任务与微任务

    今天看到这样一道面试题: //请写出输出内容 async function async1() { console.log('async1 start'); await async2(); consol ...

随机推荐

  1. SpringBoot自定义注解、AOP打印日志

    前言 在SpringBoot中使用自定义注解.aop切面打印web请求日志.主要是想把controller的每个request请求日志收集起来,调用接口.执行时间.返回值这几个重要的信息存储到数据库里 ...

  2. c++实现文件复制并修改相应属性

    问题描述 完成一个目录复制命令mycp,包括目录下的文件和子目录, 运行结果如下: beta@bugs.com [~/]# ls –la sem total 56 drwxr-xr-x 3 beta ...

  3. Java生鲜电商平台-redis缓存在商品中的设计与架构

    Java生鲜电商平台-redis缓存在商品中的设计与架构 说明:Java开源生鲜电商平台-redis缓存在商品中的设计与架构. 1. 各种计数,商品维度计数和用户维度计数 说起电商,肯定离不开商品,而 ...

  4. rabbitmq 实现多个消费队列

    1.将消费程序复制重新生成一个. 2.channel.BasicQos(0, 1, false); 空闲的先消费

  5. ANDROID培训准备资料之四大组件的简单介绍

    Android四大组件是一个android app 最基本的组成部分,这篇博客主要给大家简单的介绍一下四种组件 (1)Activities (2)Services (3)BroadcastReceiv ...

  6. 结对编程(-java-实现)

    一 .Github项目地址:https://github.com/mushan520/Four-fundamental-rules-java.git                           ...

  7. InnoDB Multi-Versioning

    InnoDB 是一个数据多版本的存储引擎,它会保持它修改的数据的旧版本数据以此来支持事务特性,比如并发操作和事务的回滚.这些旧版本数据存储在一个叫做rollback segment的数据结构中(回滚段 ...

  8. 6. [mmc subsystem] mmc core(第六章)——mmc core主模块

    一.说明 1.mmc core概述 mmc core主模块是mmc core的实现核心.也是本章的重点内容. 对应代码位置drivers/mmc/core/core.c. 其主要负责如下功能: mmc ...

  9. Git学习笔记1-Git基础

    1.创建版本库 $ mkdir /d/learngit #创建空目录 $ cd learngit #进入目录 $ git init #将该目录初始化成Git仓库 2.配置信息 1)配置用户信息: $ ...

  10. 初识v4l2(五)-------v4l2_ioctl浅析

    上一篇文章中,已经介绍了v4l2_open.v4l2_read.v4l2_write的调用过程,相对于v4l2_ioctl,它们是比较简单的.下面来分析v4l2_ioctl.注意在这里还是分析以viv ...