宏任务: setTimeout 、 setInterval 、 DOM事件、Ajax请求
DOM渲染
微任务: Promise、async/await
const set1 = setTimeout(function(){
console.log('set1')
setTimeout(function(){
console.log('set3')
})
new Promise(function(resolve){
resolve()
}).then(function(){
new Promise(function(resolve){
resolve()
}).then(function(){
console.log('then5')
})
console.log('then6')
})
})
new Promise(function(resolve){
console.log('pr1');
resolve()
}).then(function(){
console.log('then1')
new Promise(function(resolve){
resolve()
}).then(function(){
new Promise(function(resolve){
resolve()
}).then(function(){
console.log('then4')
})
console.log('then2')
})
})
const set2 = setTimeout(function(){
console.log('set2')
})
console.log(2)
上面代码执行结果:
pr1
2
then1
then2
then4
set1
then6
then5
set2
set3
首先同步代码打印结果 --- pr1 、1 (new Promise是同步的,resolve、reject更改状态,如果有then函数则会丢入微任务队列)
set1、set2 为setTimeout 函数,会丢入宏任务队列
当同步代码执行完,先执行微任务队列的任务,
打印 --- then1 ,同时又丢了一个 then函数到 微任务,@1 则继续执行 微任务(因为一定会先执行完微任务才会执行宏任务)
打印 --- then2, 重复上步骤
打印 --- then4
到此,微任务队列清空,接下来按顺序执行宏任务
打印 --- set1
此时又丢了一个 微任务到队列 和一个 宏任务到队列
根据打印结果,先打印的是 then6 then5 , 而不是 set2 , 这里我理解的是 每次执行完一个 异步队列任务,都会先询问还有 微任务没,没有再询问还有宏任务没(@1 处 也是因为如此)
未完待续......
执行顺序: 微任务 > DOM渲染 > 宏任务