【Web技術】1055- 如何理解單線程的JavaScript及其工作原理

隨着JavaScript的日益流行,團隊也利用其在前端,後端,混合APPS,嵌入式設備以及更多設備等開發棧中諸多層面的支持,JavaScript能創造出令人驚歎的軟件,開發就必須更加深入瞭解JavaScript語言的內部工作機制!

此篇文章會詳細地研究並解釋JavaScript的工作原理,通過了解這些細節,通過合理地使用提供的APIs,你將能夠寫出更好的,非阻塞的程序。

一、單線程的來源

幾乎所有人都已經聽過V8引擎的概念,並且很多人知道JavaScript是單線程的,JavaScript作爲瀏覽器腳本語言,它的主要用途是與用戶交互,那麼爲什麼JavaScript是單線程呢?如果JavaScript是多線程,當頁面更新內容的時候、用戶又觸發了交互,這時候線程間的同步問題會變得很複雜,爲了避免複雜性,故JavaScript被設計成單線程。

二、JavaScript引擎

谷歌V8引擎是一個流行的JavaScript引擎。這裏有一個簡單的視圖來描繪其大概模樣。

image.png

引擎包括兩個組件:

  • 內存堆——進行內存分配的區域
  • 調用棧——代碼執行時棧中的位置

三、運行時

幾乎每個JavaScript開發者都使用過一些瀏覽器 API(比如setTimeout)。然而這些API並不是引擎所提供的。這些Web API是瀏覽器提供的,還有DOM事件,AJAX及其它。它們怎麼執行呢,實際情況有點複雜。

於是乎,就有了如此流行的事件循環(也稱event loop或事件輪詢)和回調隊列。

四、調用棧

前面我們說過,JavaScript是單線程的編程語言,這意味着只有一個調用棧。這樣它只能一次做一件事情。調用棧是一種數據結構。當執行進入一個函數,把它置於棧的底部。如果從函數中返回則從棧底部移除函數。這就是調用棧所做的事情。
舉個🌰子,看如下代碼:

fucntion multiply(x,y) {
    return x * y;
}
function printSquare(x{
    var s = mulitiply(x,x);
    console.log(s);
}
printSquare(s);

當引擎開始執行這段代碼的時候,調用棧會被清空,之後產生如下步驟:

image.png

五、堆棧溢出

一旦達到最大調用棧大小的時候發生。這種情況相當容易發生。特別是當你使用遞歸時,看下面的代碼:

function foo () {
    foo();
}
foo();

當引擎開始執行這段代碼的時候,它開始調用foo函數。這個函數,然而會遞歸併開始調用其自身而沒有任何結束條件。所以在每步執行過程中,調用堆棧會反覆添加foo函數。就會出現如下情況:

當調用棧中的函數調用次數超過了調用棧的實際大小,瀏覽器決定拋出一個錯誤,如下圖所示:
小夥伴們可以自己在瀏覽器的控制檯裏試試!

六、事件循環(Event Loop)

又該拿出那張經典的圖了~

image.png

Event Loop 負責執行代碼、收集和處理事件以及執行隊列中的子任務。

具體包括:

  • Javascript 有一個主線程和執行棧,所有的任務都會被放到調用棧等待主線程執行
  • 同步任務會被放在調用棧中,按照順序等待主線程依次執行
  • 主線程之外存在一個任務隊列,所有任務在主線程中以執行棧的方式運行
  • 同步任務都在主線程上執行,棧中代碼在執行的時候會調用 Web API,此時會產生一些異步任務
  • 異步任務會在有了結果(比如被監聽的事件發生時)後,將註冊的回調函數放入任務隊列中
  • 執行棧中任務執行完畢後,此時主線程處於空閒狀態,會從任務隊列中獲取任務進行處理

以上過程會不斷重複,這就是瀏覽器的運行機制,也是Event Loop。

最後

Event Loop 我們還得繼續,理解它是突破前端第一層天花板的畢竟之路!


關於本文

來源:_啊嗚

https://juejin.cn/post/6991241111167565860

1. JavaScript 重溫系列(22篇全)
2. ECMAScript 重溫系列(10篇全)
3. JavaScript設計模式 重溫系列(9篇全)
4.  正則 / 框架 / 算法等 重溫系列(16篇全)
5.  Webpack4 入門(上) ||  Webpack4 入門(下)
6.  MobX 入門(上)  ||   MobX 入門(下)
7. 120 +篇原創系列彙總

回覆“加羣”與大佬們一起交流學習~

點擊“閱讀原文”查看 130+ 篇原創文章

本文分享自微信公衆號 - 前端自習課(FE-study)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章