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

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

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

掘金上面盗张图记录一下

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

先看个例子

setTimeout(() => {
//执行后 回调一个宏事件
console.log('内层宏事件3')
}, 0)
console.log('外层宏事件1'); new Promise((resolve) => {
console.log('外层宏事件2');
resolve()
}).then(() => {
console.log('微事件1');
}).then(()=>{
console.log('微事件2')
})

我们看看打印结果

外层宏事件1
外层宏事件2
微事件1
微事件2
内层宏事件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执行机制就理解了

//主线程直接执行
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进入第一个宏任务进入主线程, 直接打印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. DevExpress的TreeList实现节点上添加自定义右键菜单并实现删除节点功能

    场景 Winform控件-DevExpress18下载安装注册以及在VS中使用: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1 ...

  2. Python - 获取本机IP地址、Mac地址

    Python - 获取本机IP地址.Mac地址 在python中获取ip地址和在php中有很大不同,在php中往往比较简单.那再python中怎么做呢? 直接看代码: # Python - 获取本机I ...

  3. idea修改filetype

    settings/editor/file types把不小心改成Text类型的文件的wildcard去掉即可.

  4. Vim操作:打开文件

    1.打开文件并定位到某一行 vim +20 vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php # 定位至第20行 2 ...

  5. Ext学习之路——Ext.application

    Ext.application({ name: 'MyApp', launch: function() { Ext.create('Ext.container.Viewport', { items: ...

  6. js实现复制功能兼容ios

    html: <div id="copyBT">这是要复制的1内容</div> <a id="contentas">这是复制按 ...

  7. 那些年我们走过的坑,对Fortify的漏洞进行总结

    1.修复方案,过滤引起Log Forging漏洞的敏感字符的公共方法 /** * Log Forging漏洞校验 * @param logs * @return */ public static St ...

  8. 201871010112-梁丽珍《面向对象程序设计(java)》第十一周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  9. 201871010136-赵艳强《面向对象程序设计(java)》第十五周学习总结

    201871010136-赵艳强<面向对象程序设计JAVA>第十五周实验总结   项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh 这 ...

  10. Docker bridge、host、container other、overlay 网络模式

    docker run创建Docker容器时,可以用--net 选项指定容器的网络模式,Docker有以下5种网络模式: bridge模式:使用–net =bridge指定,默认设置: host模式:使 ...