javaScript分为宏任务和微任务
- 当js开始执行的时候,就是开启一个宏任务,在宏任务中执行一条条的指令
- 宏任务能够同时拥有多个,但会按顺序一个一个执行
- 每个 宏任务后面都可以有一个微任务队列,若是微任务队列中有指令或方法那么就会执行,若是没有,则开始执行下一个宏任务,直到宏任务执行完为止 微任务至关于宏任务的小尾巴
- 为何有了宏任务,还会有微任务存在?由于宏任务太占用性能,当须要一些较早就准备好的方法,排在最后才执行的时候,又不想新增一个宏任务,那么就能够把这些方法,一个一个的放在微任务队列里面,在这个宏任务中的代码执行完后,就会执行微任务队列。
常见宏任务与微任务
宏任务 | 微任务 |
---|---|
script(可以理解为外层同步代码) | Promise.resolve().then |
setTimeout()/setInterval | process.nextTick(Node.js) |
setImmediate,I/O(Node.js) | MutaionObserver |
process.nextTick 优先于其他微任务的执行
setImmediate 也会优先于 setTimeout
执行模式
console.log('同步-0.1')
Promise.resolve().then(() => {
console.log('P-1.1')
})
setTimeout(() => {
console.log('S-1.1')
});
Promise.resolve().then(() => {
console.log('P-1.2')
}
setTimeout(() => {
console.log('S-1.2')
});
console.log('同步-0.2')
执行结果
同步-0.1
同步-0.2
P-1.1
P-1.2
S-1.1
S-1.2
根据开头的4点提示,代码执行的场景如下
开始执行当前宏任务 script
1.遇到Promise 把异步代码放入微任务中,继续执行
2.遇到setTimeout 是宏任务,需要建立第二个宏任务 将要执行的代码放进去,继续执行下面代码
3.又遇到Promise 把异步代码再次放入微任务中,任务中已经有代码了,但是不妨碍继续往里面放置
4.又遇到setTimeout 后面有第二个宏任务了,建立第三个宏任务
5.代码执行完毕 script宏任务执行完毕,执行一下小尾巴--微任务中的代码,有的话直接执行
6.两个微任务执行完毕,刚刚微任务里面有没有新的Promise.resolve().then微任务,有的话直接执行!只要看到里面有微任务就放在这里面执行!若是遇到setTimeout()继续开一个宏任务!
7.微任务所有执行完毕! 继续执行下一个宏任务!
.....
console.log('同步-0.1')
Promise.resolve().then(() => {
console.log('P-1.1')
Promise.resolve().then(() => { // 新加行
console.log('P-2.1') // 新加行
Promise.resolve().then(() => { // 新加行
console.log('P-3.1') // 新加行
}) // 新加行
}) // 新加行
})
setTimeout(() => {
console.log('S-1.1')
});
Promise.resolve().then(() => {
console.log('P-1.2')
})
setTimeout(() => {
console.log('S-1.2')
});
console.log('同步-0.2')
结果
同步-0.1
同步-0.2
P-1.1
P-1.2
P-2.1
P-3.1
S-1.1
S-1.2