前言
什么是宏观任务,什么是微观任务?
`宏任务:宿主(浏览器)发起的任务我们可以称之为宏观任务(macrotask)
script、setTimeout、setInterval、I/O、UI交互事件、postMessage、MessageChannel、setImmediate(Node.js 环境)
微任务:引擎(js)自己发起的任务叫做微观任务(microtask)
promise async await `
js执行宏任务和微任务的联系:
`先执行宏任务再执行当前宏任务内的微任务(在此过程中将遇到的微宏任务依次推入到eventqueue,
先进入eventqueue的任务会被先执行),执行完当前宏任务内的所有微任务之后,再执行下一个宏任务,
以此循环,当然在微宏任务中同步任务会优先执行,而整体的scrpt标签就是第一个执行的宏任务`
tips:摘抄某位大佬话语
Promoise相关
`Promise中的异步体现在then和catch中,所以写在Promise中的代码是被当做同步任务立即执行的。
而在async/await中,在出现await出现之前,其中的代码也是立即执行的实际上await是一个让出线程的标志。
await后面的表达式会先执行一遍,将await后面的代码加入到microtask(微观任务)中`
示例(最近看到的经典题)
题解:
1.script是第一个宏任务
2.先执行当前宏观里的所有同步任务(主线程任务),再执行当前宏观里的所有微观任务,再执行下一个宏观任务,
即script宏(同->微)->下一个宏(同->微)->....
同步任务队列 console.log(4)-> async1()-> async2()-> console.log(8)
console.log(4); 同步任务 所以第一步打印4
async1(); 返回的是一个promise,promise本身是同步,所以 第二步打印1,并且将await之后的放到微观任务队列
async2(); 同步任务打印3,
promise();promise.then之前同步任务打印6,并将promise.then异步任务放到微观任务队列
console.log(8);同步任务打印8
微观任务队列 consol.log(2)-> console.log(7)
consol.log(2) 微观任务打印2
console.log(7) 微观任务打印7
宏观任务 setTimeout
setTimeout(function(){
console.log(5) 宏观任务打印5
})
打印顺序
同步4->同步1->同步3->同步6->同步8->微观2->微观7->宏观->5
图解:
其它案例(来小试牛刀一下吧)
题一:
async function async1() {
console.log('async1 start')
await async2()
console.log('async1 end')
}
async function async2() {
new Promise(resolve => {
console.log('promise1')
resolve()
})
.then(() => {
console.log('promise2')
})
}
console.log('script start')
setTimeout(() => {
console.log('setTimeout')
}, 0);
async1()
new Promise(resolve => {
console.log('promise3')
resolve()
})
.then(() => {
console.log('promise4')
})
console.log('script end')
题二:
Promise.resolve().then(()=>{
console.log('Promise1')
setTimeout(()=>{
console.log('setTimeout2')
},0)
})
setTimeout(()=>{
console.log('setTimeout1')
Promise.resolve().then(()=>{
console.log('Promise2')
})
},0)
题三:
async function async1() {
console.log('async1 start')
await async2()
setTimeout(() => {
console.log('setTimeout1')
}, 0)
}
async function async2() {
setTimeout(() => {
console.log('setTimeout2')
}, 0)
}
console.log('script start')
setTimeout(() => {
console.log('setTimeout3')
}, 0);
async1()
new Promise(resolve => {
console.log('promise1')
resolve()
})
.then(() => {
console.log('promise2')
})
解答
1."script start"
"async1 start"
"promise1"
"promise3"
"script end"
"promise2"
"async1 end"
"promise4"
"setTimeout"
2.
"Promise1"
"setTimeout1"
"Promise2"
"setTimeout2"
3.
"script start"
"async1 start"
"promise1"
"script end"
"promise2"
"setTimeout3"
"setTimeout2"
"setTimeout1"