宏任務包括:<script>整體代碼、setTimeout
、setInterval
、setImmediate
、Ajax
、DOM事件
微任務:process.nextTick
、MutationObserver
、Promise.then catch finally
JS是單線程,碰見同步執行同步 直到執行完畢,遇到異步放到執行隊列中去,異步(宏任務和微任務),在異步中微任務是優於宏任務執行的
1 setTimeout(_ => console.log(4)) 2 3 new Promise(resolve => { 4 resolve() 5 console.log(1) 6 }).then(_ => { 7 console.log(3) 8 }) 9 10 console.log(2)
整個這一串代碼我們所在的層級我們看做一個任務,其中我們先執行同步代碼。第一行的 setTimeout 是異步代碼,跳過,來到了 new Promise(…) 這一段代碼。前面提到過,這種方式是一個構造函數,是一個同步代碼,所以執行同步代碼里面的函數,即 console.log(1),接下來是一個 then 的異步,跳過。最后一個是一段同步代碼 console.log(2)。所以,這一輪中我們知道打印了1, 2兩個值。接下來進入下一步,即之前我們跳過的異步的代碼。從上往下,第一個是 setTimeout,還有一個是 Promise.then()。setTimeout 是宏任務的異步,Promise.then()是微任務的異步,微任務是優先於宏任務執行的,所以,此時會先跳過 setTimeout 任務,執行兩個 Promise.then() 的微任務。所以此時會執行 console.log(3) 函數。最后就只剩下 setTimeout 函數沒有執行,所以最后執行 console.log(4)。
綜上:最后的執行結果是 1, 2, 3, 4。
解釋下:
setTimeout就是作為宏任務來存在的,而Promise.then則是具有代表性的微任務