詳解JavaScript運行機制以及概念分析
對JavaScript有個很模糊的印象,它是單執行緒異步的。本文主要來說說JavaScript到底是怎麼運作的。但在這之前,讓我們先理一下這些概念(現學現賣)。
基本概念
執行緒與行程
行程(Process)是系統資源分配與調度的單元。一個運作著的程式就對應了一個行程。一個進程包括了運行中的程式和程式所使用到的記憶體和系統資源。如果是單核心CPU的話,在同一時間內,有且只有一個行程在運作。但是,單核心CPU也能實現多任務同時運行,例如你邊聽網易雲音樂的每日推薦歌曲,邊在網易有道雲筆記上寫博文。這算開了兩個進程(多進程),那運行的機制就是一會兒播放一下歌,一會兒響應一下你的打字,但由於CPU切換的速度很快,你根本感覺不到,以至於你認為這兩個進程是在同時運行的。進程之間是資源隔離的。
那線程(Thread)是什麼?執行緒是進程下的執行者,一個行程至少會開啟一個執行緒(主執行緒),也可以開啟多個執行緒。例如網易雲音樂一邊播放音頻,一邊顯示歌詞。多進程的運行其實也就是透過進程中的執行緒來執行的。一個行程下的執行緒是共享資源的。當多個執行緒同時操作同一個資源的時候,就會出現資源爭搶的問題。這又是另外一個問題了。
並行與並行
並行(Parallelism)是指程式的運作狀態,在同一個時間內有幾件事情並行在處理。由於一個執行緒在同一時間只能處理一件事情,所以並行需要多個執行緒在同一時間執行多件事情。
而並發(Concurrency)是指程式的設計結構,在同一時間內多件事情能被交替地處理。重點是,在某個時間內只有一件事情在執行。例如單核心CPU能實現多任務運行的過程就是並發的。
同步與非同步
同步非同步是指程式的行為。同步(Synchronous)是程式發出呼叫的時候,一直等待直到回傳結果,沒有結果之前不會回傳。也就是說,同步是呼叫者主動等待呼叫過程。
非同步(Asynchronous)是發出呼叫之後,馬上回傳,但不會馬上回傳結果。呼叫者不必主動等待,當被呼叫者得到結果之後會主動通知呼叫者。
舉個例子,去奶茶店買飲料。同步就是,一個顧客說出需求(請求),然後一直等著服務生做好飲料,顧客拿到自己點的飲料之後才離開;然後下一個顧客繼續重複上述過程。非同步就是,顧客先排隊點單,點完之後拿著單子在一邊,等服務生做好之後會叫號,叫到你了你去拿就好。
所以執行緒跟同步異步沒有直接的關係,單執行緒也是可以實現異步的。至於實現的方式,以下會具體說到。
阻塞與非阻塞
阻塞與非阻塞是指等待狀態。阻塞(Blocking)是指呼叫在等待的過程中線程被「掛起」(CPU資源被分配到其他地方去了)。
非阻塞(Non-blocking)是指等待的過程CPU資源還在該執行緒中,執行緒還能做其他的事情。
以剛才排隊買飲料的例子,阻塞就是你在等待的時候什麼事情也做不了,而非阻塞是你在等待的時候可以管自己先做其他的事情。
所以,同步可以阻塞也可以非阻塞,非同步可以阻塞也可以非阻塞。
單執行緒的JS
大概理清楚上述概念之後呢,就知道單執行緒和非同步是沒有矛盾的。那JS是如何執行的呢? JS其實就是一門語言,說是單執行緒還是多執行緒得結合具體運行環境。 JS的運作通常是在瀏覽器中進行的,具體由JS引擎去解析和運行。下面我們來具體了解瀏覽器。
瀏覽器
目前最受歡迎的瀏覽器為:Chrome,IE,Safari,FireFox,Opera。瀏覽器的核心是多執行緒的。一個瀏覽器通常由以下幾個常駐的執行緒:
渲染引擎執行緒:顧名思義,該執行緒負責頁面的渲染
- ##JS引擎執行緒:負責JS的解析與執行
- 定時觸發器執行緒:處理定時事件,例如setTimeout, setInterval ##事件觸發執行緒:處理DOM事件
- 非同步http請求執行緒:處理http請求
- #需要注意的是,渲染執行緒和JS引擎執行緒是不能同時進行的。渲染線程在執行任務的時候,JS引擎線程會被掛起。因為JS可以操作DOM,若在渲染中JS處理了DOM,瀏覽器可能就不知所措了。
JS引擎
通常講到瀏覽器的時候,我們會說到兩個引擎:渲染引擎和JS引擎。渲染引擎就是如何渲染頁面,Chrome/Safari/Opera用的是Webkit引擎,IE用的是Trident引擎,FireFox用的是Gecko引擎。不同的引擎對同一個樣式的實作不一致,就導致了經常被人詬病的瀏覽器樣式相容性問題。這裡我們不做具體討論。
JS引擎可以說是JS虛擬機,負責JS程式碼的解析與執行。通常包括以下幾個步驟:
詞法分析:將原始程式碼分解為有意義的分詞
- ##語法分析:用語法分析器將分詞解析成語法樹
- 程式碼產生:產生機器能執行的程式碼
- 程式碼執行
var x = 10; function foo(){ var y=20; function bar(){ var z=15; } bar(); } foo();
foo()的時候,就進入了foo上下文,當然此時全域上下文還在。當執行
bar()的時候,又進入了bar上下文。執行完畢
bar(),回到foo上下文。執行完
foo(),又回到全域上下文。所以,執行過程執行上下文會形成一個呼叫堆疊(Call stack),先進後出。
// 进栈 3 bar Context => => 2 foo Context => 2 foo Context 1 global Context 1 global Context 1 global Context // 出栈 3 bar Context 2 foo Context => 2 foo Context => => 1 global Context 1 global Context 1 global Context
- setTimeout
- setInterval
- 事件監聽
- #Ajax請求
- etc. .
function foo(){ console.log(1); } function bar(){ console.log(2); } foo(); setTimeout(function cb(){ console.log(3); }); bar();
foo(),進入了foo上下文環境;執行
console.log(1),控制台輸出1;foo上下文環境出棧,運行至
setTimeout,交給
瀏覽器的定時處理線程;運行至bar() ,進入了bar上下文環境;執行
console.log(2),控制台輸出2;foo上下文環境出棧;等到
瀏覽器執行緒執行完setTimeout,返回
cb()回呼函數至目前
任務佇列;當發現執行堆疊為空時,瀏覽器的JS引擎會執行一次循環,將事件佇列的隊首出隊至JS執行堆疊中;執行cb(),進入cb上下文環境;執行
console.log(3),控制台輸出3;事件佇列為空,全域上下文出棧。
瀏覽器執行緒,任務佇列以及JS引擎。所以,我們可以看出,JS的非同步請求,借助了而它所在的運行環境瀏覽器來處理並且傳回結果。而且,這也解釋了為什麼那些回呼函數的this指向
window,因為這些非同步的程式碼都是在全域上下文環境下執行的。
- JavaScript:徹底理解同步、非同步與事件循環(Event Loop)
- 還在疑惑並發和並行?
- IMWeb社群 瀏覽器進程?線程?傻傻分不清楚!
- Javascript是單一執行緒的深入分析
- JavaScript單執行緒與瀏覽器事件循環簡述
- AlloyTeam 【轉向Javascript系列】從setTimeout說事件循環模型
- 小鬍子JavaScript異步程式設計原理 ##阮一峰JavaScript 運行機制詳解:再談Event Loop
- 【樸靈註解】JavaScript 運作機制詳解:再談Event Loop
Philip Roberts: Help, I'm stuck in an event-loop.
Philip Roberts: What the heck is the event loop anyway?
jquery中Ajax的非同步與同步
以上是詳解JavaScript運行機制以及概念分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

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

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

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

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

用法:在JavaScript中,insertBefore()方法用於在DOM樹中插入一個新的節點。這個方法需要兩個參數:要插入的新節點和參考節點(即新節點將要插入的位置的節點)。

JavaScript是一種廣泛應用於Web開發的程式語言,而WebSocket則是一種用於即時通訊的網路協定。結合二者的強大功能,我們可以打造一個高效率的即時影像處理系統。本文將介紹如何利用JavaScript和WebSocket來實作這個系統,並提供具體的程式碼範例。首先,我們需要明確指出即時影像處理系統的需求和目標。假設我們有一個攝影機設備,可以擷取即時的影像數
