為什么瀏覽器是單線程的,單線程又是怎么實現的


JavaScript 為什么是單線程的?JavaScript 為什么需要異步?JavaScript 單線程又是如何實現異步的?

1.JavaScript 為什么是單線程的?

  現在有 2 個線程 process1 process2,假設 JavaScript 是多線程的,所以他們可以對同一個 dom 同時進行操作。process1 刪除了該 dom,而 process2 編輯了該 dom,同時下達 2 個矛盾的命令,瀏覽器究竟該如何執行呢?這樣想,JavaScript 為什么被設計成單線程應該就容易理解了吧。

2.JavaScript 為什么需要異步?

  如果 JavaScript 中不存在異步,只能自上而下執行,如果上一行解析時間很長,那么下面的代碼就會被阻塞。對於用戶而言,阻塞就意味着"卡死",這樣就導致了很差的用戶體驗,所以 JavaScript 中存在異步執行。

3.JavaScript 單線程又是如何實現異步的呢?

  通過一個題看一下

setTimeout(function () {
  console.log(1)
}, 0)

Promise.resolve(function () {
  console.log(2)
})

new Promise(function (resolve) {
  console.log(3)
})

console.log(4)

// 上述代碼的輸出結果是什么???

解釋

// 遇到 setTimeout 將 setTimeout 回調放入宏任務隊列中
setTimeout(function () {
  console.log(1)
}, 0)

// 遇到了 promise,但是並沒有 then 方法回調 
// 所以這句代碼會在執行過程中進入我們當前的執行上下文 緊接着就出棧了
Promise.resolve(function () {
  console.log(2)
})

// 遇到了一個 new Promise,Promise 有一個原則就是在初始化 Promise 的時候Promise 內部的構造器函數會立即執行,
// 因此在這里會立即輸出一個 3,所以這個 3 是第一個輸出的
new Promise(function (resolve) {
  console.log(3)
})
// 然后第二個輸出 4  當代碼執行完畢后回去微任務隊列查找有沒有任務,
// 發現微任務隊列是空的,那么就去宏仁務隊列中查找,發現有一個我們剛剛放進去的setTimeout 回調函數,
// 那么就取出這個任務進行執行,所以緊接着輸出1
console.log(4)

答案 ==》 3  4 2 1

任務隊列
當遇到一個異步事件后,JavaScript 引擎並不會一直等待異步事件返回結果,而是會將這個事件掛在與執行棧不同的隊列中,我們稱之為任務隊列。
這些任務又被細分為宏任務和微任務

在主線程的任務 全部執行完畢,就會清空微任務,然后去宏任務隊列中取出一條宏任務,放在主任務中執行,主任務執行完畢,清空微任務,再去宏任務中取任務,一直循環執行

宏任務(macrotask):script(全局任務),setTimeout ,setInterval ,setImmediate (node.js 獨有),I/O(磁盤讀寫或網絡通信) ,UI rendering(UI交互事件)
微任務(microtask):process.nextTick (node.js 獨有), Promise.then

 


免責聲明!

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



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