首頁 web前端 前端問答 JavaScript的單線程你真的理解了嗎

JavaScript的單線程你真的理解了嗎

Jan 10, 2022 pm 07:08 PM
html javascript 前端

這篇文章為大家帶來了我們的JavaScript單執行緒的相關知識,JavaScript是一門單執行緒的語言,為什麼JavaScript可以一邊執行定時器一邊執行函數,希望對大家有幫助。

JavaScript的單線程你真的理解了嗎

1. 行程與執行緒

1.1 行程(Process)

是電腦中的程式關於某資料集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是作業系統結構的基礎。在當代面向執行緒設計的電腦結構中,進程是執行緒的容器。程序是指令、資料及其組織形式的描述,流程是程式的實體。是電腦中的程式關於某資料集合上的一次運行活動,是系統進行資源分配與調度的基本單位,是作業系統結構的基礎。程序是指令、資料及其組織形式的描述,過程是程式的實體。

我們在這裡將進程比喻為工廠的車間,它代表CPU所能處理的單一任務。任一時刻,CPU總是運行一個進程,其他進程處於非運行狀態。

1.2 執行緒(thread)

是作業系統能夠進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運作單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以並發多個線程,每個線程並行執行不同的任務。

這裡把線程比喻一個車間的工人,即一個車間可以允許由多個工人協同完成一個任務。

2. 多線程的瀏覽器

瀏覽器核心是多線程,在核心控制下各線程相互配合以保持同步,一個瀏覽器通常由以下常駐執行緒組成:

  • GUI 渲染執行緒

  • #JavaScript引擎執行緒

  • ##事件觸發線程

  • 定時觸發器執行緒

  • 非同步http請求執行緒

JavaScript的單線程你真的理解了嗎

我們看到了JS引擎線程,非常的熟悉,沒有錯,這裡是我們執行javascript腳本程式的地方。

而JS引擎是多執行緒的,單執行緒是指JS引擎執行JS時只分了一個執行緒給他執行,意思是JS引擎分配了一個執行緒給JavaScript執行,也就是我們所說的單線程。

2.1 這裡再說下JS的執行機制

由於JavaScript是單執行緒(一個Tab頁內中無論何時都只有一個JS執行緒在執行JavaScript程式) 。

所以我們需要依賴任務佇列來進行JavaScript程式碼的執行。

JS引擎會一直等待著任務佇列中任務的到來,然後執行任務。

同步任務這麼執行當然沒問題,我們把任務都放在任務佇列裡,一個一個執行,邏輯很清晰。但是,如果我們向後台發送請求,發送加接收這段時間可能需要一秒,我們不能等它一秒吧,如果請求五次,那就等五秒?顯示不符合我們的需求,所以,我們需要非同步任務來處理這個問題。

2.2 同步任務和非同步任務

同步任務是指在主執行緒上排隊執行的任務,只有前一個任務執行完畢,才能繼續執行下一個任務,當我們開啟網站時,網站的渲染過程,例如元素的渲染,其實就是一個同步任務

非同步任務是指不進入主線程,而進入任務佇列的任務,只有任務佇列通知主線程,某個非同步任務可以執行了,該任務才會進入主線程,當我們打開網站時,像圖片的加載,音樂的加載,其實就是一個非同步任務。

大家一定對Event Loop有比較具象的認知,這邊我不詳細說了,不懂可以跟我說,我再說就是了。

3. 本文重重點--可直接看

但是,大家有沒有對任務佇列抱持疑問?這是個對象?是個數組?照我的邏輯來說,我們JavaScript主執行緒執行同步函數,非同步函數可以放在任務佇列裡,這個任務佇列可以是個對象,當我們執行完同步任務的時候,把這個物件(任務佇列)壓進主線程中就可以了,但是事實並不我想的這樣的。

Evnet Loop的任務佇列放在了瀏覽器的事件觸發線程中,當JS引擎執行非同步函數的時候,會將非同步任務放在事件觸發線程中,當對應的非同步任務符合觸發條件被觸發時,事件觸發線程會把非同步任務加到JS引擎中的主線程的隊尾,等待執行。

是不是跟我們想像的JavaScript單執行緒不太一樣?好吧,確實不太一樣,所以最後的結論是,我們所說的任務隊列竟然是一個線程。

然後,說回我們開頭剛開始說過的定時器,大家基本上也能猜出來了,它是由定時器線程控制的。

因為JavaScript是單執行緒的, 如果處於阻塞執行緒狀態就會影響記計時的準確,因此很有必要單獨開一個執行緒用來計時。

當使用setTimeout或setInterval時,它需要計時器執行緒計時,計時完成後就會將特定的事件推入事件佇列中。

4. 結論

所以說,我們說JavaScript是單線程的沒錯,就是天王老子來了它也是單線程的,但是我們的Event Loop和定時器是放在其他執行緒的。

5. V8引擎--擴展

V8引擎是一個JavaScript引擎實現,最初由一些語言方面專家設計,後來被Google收購,隨後谷歌對其進行了開源。

V8使用C 開發,在執行JavaScript之前,比較其它的JavaScript的引擎轉換成字節碼或解釋執行,V8將其編譯成原生機器碼(IA-32, x86-64, ARM , or MIPS CPUs),並且使用瞭如內聯緩存(inline caching)等方法來提高效能。

有了這些功能,JavaScript程式在V8引擎下的運行速度媲美二進位程式。 V8支援眾多作業系統,如windows、linux、android等,也支援其他硬體架構,如IA32,X64,ARM等,具有很好的可移植和跨平台特性。

5.1 工作流程

V8引擎在執行JavaScript的過程中,主要有兩個階段:編譯和運行,與C 的執行前完全編譯不同的是,JavaScript需要在使用者使用時完成編譯和執行。在V8中,JavaScript相關程式碼並非一下完成編譯的,而是在某些程式碼需要執行時,才會進行編譯,這就提高了回應時間,減少了時間開銷。在V8引擎中,原始碼先被解析器轉變為抽象語法樹(AST),然後使用JIT編譯器的全代碼產生器從AST直接產生本地可執行程式碼。這個過程不同於JAVA先生成字節碼或中間表示,減少了AST到字節碼的轉換時間,提高了程式碼的執行速度。但由於缺少了轉換為字節碼這一中間過程,也就減少了優化程式碼的機會。

V8引擎編譯本機程式碼時使用的主要類別如下所示:

  • #Script:表示JavaScript程式碼,即包含原始程式碼,又包含編譯之後產生的本機程式碼,也就是編譯入口,又是運行入口;

  • Compiler:編譯器類,輔組Script類來編譯生成程式碼,呼叫解釋器(Parser)來產生AST和全程式碼產生器,將AST轉變為本地程式碼;

  • AstNode:抽象語法樹節點類,是其他所有節點的基類,包含非常多的子類,後面會針對不同的子類別產生不同的本機程式碼;

  • AstVisitor:抽象語法樹的訪客類,主要用來遍歷異質的抽象語法樹;

  • FullCodeGenerator:AstVisitor類別的子類,透過遍歷AST來為JavaScript產生本機執行程式碼。

JavaScript的單線程你真的理解了嗎

JavaScript程式碼編譯的過程大致為:Script類別呼叫Compiler類別的Compile函數為其產生本機程式碼。 Compile函數先使用Parser類別產生AST,再使用FullCodeGenerator類別來產生本機程式碼。本機程式碼與特定的硬體平台密切相關,FullCodeGenerator使用多個後端來產生與平台相符的本機彙編程式碼。由於FullCodeGenerator透過遍歷AST來為每個節點產生對應的彙編程式碼,缺少了全域視圖,節點之間的最佳化也就無從談起

【相關推薦:javascript學習教學

以上是JavaScript的單線程你真的理解了嗎的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

HTML 中的表格邊框 HTML 中的表格邊框 Sep 04, 2024 pm 04:49 PM

HTML 表格邊框指南。在這裡,我們以 HTML 中的表格邊框為例,討論定義表格邊框的多種方法。

HTML 中的巢狀表 HTML 中的巢狀表 Sep 04, 2024 pm 04:49 PM

這是 HTML 中巢狀表的指南。這裡我們討論如何在表中建立表格以及對應的範例。

HTML 左邊距 HTML 左邊距 Sep 04, 2024 pm 04:48 PM

HTML 左邊距指南。在這裡,我們討論 HTML margin-left 的簡要概述及其範例及其程式碼實作。

HTML 表格佈局 HTML 表格佈局 Sep 04, 2024 pm 04:54 PM

HTML 表格佈局指南。在這裡,我們詳細討論 HTML 表格佈局的值以及範例和輸出。

HTML 輸入佔位符 HTML 輸入佔位符 Sep 04, 2024 pm 04:54 PM

HTML 輸入佔位符指南。在這裡,我們討論 HTML 輸入佔位符的範例以及程式碼和輸出。

HTML 有序列表 HTML 有序列表 Sep 04, 2024 pm 04:43 PM

HTML 有序列表指南。在這裡我們也分別討論了 HTML 有序列表和類型的介紹以及它們的範例

HTML onclick 按鈕 HTML onclick 按鈕 Sep 04, 2024 pm 04:49 PM

HTML onclick 按鈕指南。這裡我們分別討論它們的介紹、工作原理、範例以及各個事件中的onclick事件。

在 HTML 中移動文字 在 HTML 中移動文字 Sep 04, 2024 pm 04:45 PM

HTML 中的文字移動指南。在這裡我們討論一下marquee標籤如何使用語法和實作範例。

See all articles