微任务,宏任务顺序
Posted yf-html
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微任务,宏任务顺序相关的知识,希望对你有一定的参考价值。
前言
JS中整个循环当中,仅存在一个《》
理解一下概念问题 微任务,宏任务
宏任务需要多次事件循环才能执行完,微任务是一次性执行完的;
2.宏任务macrotask:
(事件队列中的每一个事件都是一个macrotask)
优先级:主代码块 > setImmediate > MessageChannel > setTimeout / setInterval
比如:setImmediate指定的回调函数,总是排在setTimeout前面
3.微任务包括:
优先级:process.nextTick > Promise > MutationObserver
需要多注意 process.nextTick 永远大于 promise.then,
原因其实很简单
在Node中,_tickCallback在每一次执行完TaskQueue中的一个任务后被调用,而这个_tickCallback中实质上干了两件事:
1.nextTickQueue中所有任务执行掉(长度最大1e4,Node版本v6.9.1)
2.第一步执行完后执行_runMicrotasks函数,执行microtask中的部分(promise.then注册的回调)
盗一张图:
但是js异步有一个机制,就是遇到宏任务,先执行宏任务,将宏任务放入eventqueue,然后在执行微任务,将微任务放入eventqueue,
这两个queue不是一个queue。当你往外拿的时候先从微任务里拿这个回掉函数,然后再从宏任务的queue上拿宏任务的回掉函数。
这张图可以看出:
- 存在微任务的话,那么就执行所有的微任务
- 微任务都执行完之后,执行第一个宏任务,
- 循环 1, 2
這樣 可以总结一下如何分析异步执行的顺序:
首先我们分析有多少个宏任务;
在每个宏任务中,分析有多少个微任务;
根据调用次序,确定宏任务中的微任务执行次序;
根据宏任务的触发规则和调用次序,确定宏任务的执行次序;
下面做個測試:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <script> console.log(‘1‘);// setTimeout(function () { console.log(‘2‘);// new Promise(function (resolve) { console.log(‘3‘);// resolve(); }).then(function () { console.log(‘4‘);// }) }, 0); new Promise(function (resolve) { console.log(‘5‘);// resolve(); }).then(function () { console.log(‘6‘);// }); setTimeout(function () { console.log(‘7‘);// new Promise(function (resolve) { console.log(‘8‘);// resolve(); }).then(function () { console.log(‘9‘);// }); }) </script> </body> </html>
测试结果为: 1->5->6->2->3->4->7->8->9
如果上面實在node 环境中
测试结果为: 1->5->6->2->3-->7->8->4->9
分析
1.浏览器环境是执行完seTimeout内部回调函数内容
2.node环境中setTimeout内部如果还有异步操作,直接跳到下一个setTimeout回调代码中。至于两个setTimeout中promose.then内部的执行顺去取决于微任务的入队顺序
以上是关于微任务,宏任务顺序的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript宏任务(macrotask)和 微任务(microtask) 执行顺序