js的執行機制——宏任務和微任務


  • 宏任務隊列可以有多個,微任務隊列只有一個;
  • 主線程上的任務是第一個宏任務;
  • 會建立宏任務的有:setTimeOut、 setInterval、 requestAnimationFrame
  • 會建立微任務的有:Promise的回調、 process.nextTick
  • 當有一個宏任務隊列執行完畢后,會執行微任務隊列中的全部內容,然后執行另一個宏任務隊列,如此反復

js代碼執行機制基本是這樣的:當遇到3中的內容時建立新的宏任務,遇到4中的內容時將其加入微任務,然后按5中的順序執行。結合下面的例子來分析一下:

console.log("1")


// setTimeOut函數不設置時間
setTimeout ( () => {
    console.log('2')
    new Promise( (resolve => {
        console.log("3")
        resolve()
    })) .then ( () => console.log("4"))
})


new Promise ( (resolve, reject) => {
    console.log("5")
    resolve()
}) .then( () => console.log('6'))


setTimeout ( () => {
    console.log('7')
})


console.log("8")

*測試發現setTimeOut不加時間與設置時間為0效果相同,都是等主線程上的代碼執行完后立即執行

分析:

js代碼從上到下執行,先遇到console.log(1),將其加入主線程的宏任務隊列,然后發現setTimeOut,為其創建第二個宏任務隊列並將其加入,其中代碼先不執行,然后遇到Promise,將其中的console.log(5)加入主線程的宏任務隊列,將then回調函數中的內容加入微任務隊列,繼續往下發現第二個setTimeOut,將其放入第三個宏任務隊列,最后將console.log(8)放入主線程宏任務隊列,到此,代碼已經完成了在不同隊列中的分布,詳細情況為:

接下來開始執行第一個宏任務隊列,分別打印1,5,8,然后執行微任務隊列,打印6,微任務隊列變為空。接着執行第二個宏任務隊列,開始執行第一個setTimeOut中的代碼:先后打印 2,3,並將回調函數中的console.log(4)加入微任務。此時第二個宏任務隊列執行完畢,開始執行微任務隊列,打印 4。接着執行第三個宏任務隊列,打印 7。執行完畢。所以最終輸出順序為:15862347。

個人理解,若有錯誤,歡迎指正


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM