js事件循环,它分为主任务,宏任务和微任务,它会先执行主任务,直到结束,任务再执行微任务,第一层微任务执行完毕,它会获取执行栈是否还有没执行的任务,若没有,再执行宏任务,它是一层一层去执行的
宏任务:
script(整体代码)
setTimeout, setInterval, setImmediate
微任务:
process.nextTick
Promise
MutationObserver(html5新特性)
微任务始终优先于宏任务执行,举个例子:
1. console.log('第一次循环主执行栈开始')
2. setTimeout(function() {
3. console.log('第二次循环开始,宏任务队列的第一个宏任务执行中')
4. new Promise(function(resolve) {
5. console.log('宏任务队列的第一个宏任务的微任务继续执行')
6. resolve()
7. }).then(function() {
8. console.log('第二次循环的微任务队列的微任务执行')
9. setTimeout(() => {
10. console.log('第三次宏任务结束')
11. }, 0)
12. })
13. }, 0)
14. new Promise(function(resolve) {
15. console.log('第一次循环主执行栈进行中...')
16. resolve()
17. }).then(function() {
18. console.log('第一次循环微任务,第一次循环结束')
19. new Promise(function(resolve){
20. console.log('第二次微循环执行中')
21. resolve()
22. }).then(function(){
23. console.log('第二次微循环执行结束')
24. })
25. setTimeout(function() {
26. console.log('第二次循环的宏任务队列的第二个宏任务执行');
27. setTimeout(() => {
28. console.log('ddd')
29. },0)
30. })
31. })
32. console.log('第一次循环主执行栈完成')
首先事件循环到主进程,那么就执行:“第一次循环主执行栈开始”,然后执行到setTimeout,它是宏任务,那么它就会被压到宏任务队列中,等待执行,然后执行到Promise,其回调函数并不会被放入其他任务队列,(因为它会立即执行,即是同步方法)所以打印c。Promise.then是异步事件,那么它不会在同步任务中执行,所以放入微任务执行栈中等待执行,任务打印“第一次循环主执行栈完成”,到此,第一次事件循环结束,这阶段的打印内容为:
“第一次循环主执行栈开始”->“第一次循环主执行栈进行中…”->“第一次循环主执行栈完成”
接下来第二次事件循环开始,setTimeout优先级低于promise,那么先执行Promise.then,Promise中也有一个宏任务,但是它是在Promise中的,并不是顶级栈,它是在第一层setTimeout下面的,所以它不会优先执行,那么这里就会优先执行Promise,先执行他的回调,先打印"第一次循环微任务,第一次循环结束",微任务优先宏任务执行,所以下面的Promise一起执行,打印:“第二次微循环执行中”“第二次微循环执行结束”,然后执行第一层setTimeout,打印:“第二次循环开始,宏任务队列的第一个宏任务执行中”“宏任务队列的第一个宏任务的微任务继续执行”“第二次循环的微任务队列的微任务执行”,
第二次事件循环结束,结果为:
“第一次循环微任务,第一次循环结束”->“第二次微循环执行中”->“第二次微循环执行结束”->“第二次循环开始,宏任务队列的第一个宏任务执行中”->“宏任务队列的第一个宏任务的微任务继续执行”->“第二次循环的微任务队列的微任务执行”
进行第三次事件循环:
25行的setTimeout先被压如执行栈,所以优先执行,执行“第二次循环的宏任务队列的第二个宏任务执行”,在执行第9行:“第三次宏任务结束”,最后执行“ddd”,
最后的结果是:
“第一次循环主执行栈开始”->“第一次循环主执行栈进行中…”->“第一次循环主执行栈完成”->“第一次循环微任务,第一次循环结束”->“第二次微循环执行中”->“第二次微循环执行结束”->“第二次循环开始,宏任务队列的第一个宏任务执行中”->“宏任务队列的第一个宏任务的微任务继续执行”->“第二次循环的微任务队列的微任务执行”->“第二次循环的宏任务队列的第二个宏任务执行”->“第三次宏任务结束”->“ddd”
文中采用的例子是借鉴:关于JS事件循环机制,我今天终于整明白了