一、概念
1.宏任务MacroTask:
消息队列(回调队列)中的任务称为宏任务,是由宿主环境(浏览器或者node)提供的,不断的从消息队列中取出并被事件循环执行,宏任务在执行时,他不能获取到任务外的上下文。
宏任务包含:script (可以理解为外层同步代码),setTimeout/setInterval,setImmediate(IE/node),requestAnimationFrame,I/O,UI rendering,注册事件。
2.微任务microTask:
在当前主线程任务结束之后就立即执行,会在当前宏任务之前运行,而不是到整个任务的后面。它是由js引擎自身提供的,微任务在执行时,它能获取到任务外的上下文。
微任务包含:Promise.then catch finally,MutaionObserver,process.nextTick(node),queueMicrotask。
queueMicrotask开启一个微任务
MutaionObserver:观察器,观察一个dom对象是否发生变化,发生变化执行
二、执行顺序
先执行同步代码,遇到异步宏任务则将异步宏任务放入宏任务队列中,遇到异步微任务则将异步微任务放入微任务队列中,当所有同步代码执行完毕后,如果有微任务,再将异步微任务从队列中调入主线程执行,微任务执行完毕后再将异步宏任务从队列中调入主线程执行,一直循环直至所有任务执行完毕。
注:宏任务和微任务都是异步
三、代码示例
setTimeout(function(){
console.log('1')
})
new Promise(function(resolve){
console.log('2');
resolve();
}).then(function(){
console.log('3')
})
console.log('4')
结果:2, 4, 3, 1
Promise.resolve().then(function(){
setTimeout(() => {
console.log("2")
})
}).then(() => {
console.log(3)
})
setTimeout(() => {
console.log(1)
})
结果:3,1,2
setTimeout(function(){
console.log('1')
})
Promise.resolve().then(() => {
console.log('2')
}).then(() => {
console.log('3')
})
console.log('4')
结果:4, 2, 3, 1
setTimeout(function(){
console.log('1')
})
Promise.resolve().then(() => {
console.log('2')
}).then(() => {
console.log('3')
})
new Promise(resolve => {
console.log('4')
resolve()
}).then(() => {
console.log('5')
})
console.log('6')
结果:4, 6, 2, 5, 3, 1
1.1主线程同步行执行输出:1
console.log(1)
1.2创建第一个宏任务,并未执行和输出
setTimeout(() => { // 2.1.1宏任务执行
console.log(2) // 2.1.2同步执行,输出:2
new Promise(resolve => {
console.log(3) // 2.1.3promise同步执行,输出:3
resolve()
}).then(() => { // 2.1.4创建微任务,没有执行
console.log(4) // 2.1.7then微任务执行,输出:4
})
process.nextTick(() => { // 2.1.5创建微任务,没有执行
console.log(5) // 2.1.6微任务执行,nextTick优先then的微任务,输出:5
})
})
1.3创建了第一个微任务
process.nextTick(() => {
console.log(6) // 1.7第一个微任务执行输出了:6
})
1.4创建了第二个微任务
Promise.resolve().then(() => {
setTimeout(() => { // 1.8第二个微任务执行,创建了第三个宏任务
console.log(7) // 2.3.1宏任务执行,输出了:7
})
}).then(() => { // 1.5创建了第三个微任务
console.log(8) // 1.9第三个微任务执行,输出了:8
})
1.6创建了第二宏任务
setTimeout(() => {// 2.2.1宏任务执行
console.log(9) // 2.2.2同步执行,输出:9
process.nextTick(() => { // 2.2.3创建微任务,没输出
console.log(10) // 2.2.5微任务执行,输出:10
})
new Promise(resolve => {
console.log(11) // 2.2.4promise同步执行输出:11
resolve();
}).then(() => {
console.log(12) // 2.2.6微任务执行输出:12
})
})
结果:1, 6,8,2,3,5,4,9,11,10,12,7
总结:根据上面写的概念和执行顺序去试试做下这些题,node的方法会优先与js上的方法,按照主线程>微任务>宏任务的顺序去做,一定要确保主线程的完成再去考虑微任务和宏任务。
不懂得可以私信我!!!