宏任务
- script标签中包裹的代码
- setTimeout
- setInterval
- setImmediate
- requestAnimationFrame
- ui渲染
- io流
- ajax请求
微任务
- Promise.then()之后的,之前的都是同步的
- async、await
- process.nextTick
- MutationObserver
事件的执行流程
先执行宏任务 --> 该宏任务下有没有可执行的微任务 --> 有执行微任务 ---> 没有执行下一个宏任务
先同步后异步
setTimeout(() => {
console.log('1');
new Promise(function(resolve, reject) {
console.log('2')
setTimeout(() => {
console.log('3');
}, 0)
resolve()
}).then(function() {
console.log('4');
})
}, 0)
console.log('5');
setTimeout(() => {
console.log('6');
}, 0)
new Promise(function(resolve, reject) {
console.log('7');
resolve()
}).then(function() {
console.log('8');
}).catch(function() {
console.log('9');
})
console.log('10');
输出:
5,7,10,8,1,2,4,6,3
原则:
先同后异
流程解析:
1.遇到setTimeout先不执行,放到宏任务队列里
2.同步代码先执行,输出5
3.第二个setTimeout不执行,放到宏任务队列里
4.遇到Promise是微任务,放到微任务的队列里,.then前面是同步的,.then()是异步的,所以输出7
5.接下来是宏任务并且同步的,输出10,并且该宏任务下没有可执行的微任务
6.宏任务执行完一轮,执行微任务,输入8
7.再执行宏任务,第一个延时器,先输出1 ,遇到promise微任务,放在微任务队列里,执行同步代码执行2, 遇到延时器,不执行,放到宏任务的队列里,该宏任务下有微任务执行微任务,输出4,该宏任务执行完毕
8.执行下一个宏任务,打印6,该宏任务没有可执行的微任务
9.执行最后一个宏任务,输出3,执行完毕
特别注意
当微任务嵌套微任务时,内层微任务先执行,外层微任务后执行
setTimeout(() => {
console.log('1');
new Promise(function(resolve, reject) {
console.log('2')
resolve()
new Promise(function(resolve, reject) {
console.log('11');
resolve()
}).then(() => {
console.log('12');
})
setTimeout(() => {
console.log('3');
}, 0)
}).then(function() {
console.log('4');
})
}, 0)
console.log('5');
setTimeout(() => {
console.log('6');
}, 0)
new Promise(function(resolve, reject) {
console.log('7');
resolve()
}).then(function() {
console.log('8');
}).catch(function() {
console.log('9');
})
console.log('10');
正确结果:5, 7,10, 8, 1, 2,11,12, 4, 6, 3