1. 程式人生 > >JavaScript的單執行緒和非同步

JavaScript的單執行緒和非同步

前言

我們都知道JavaScript是單執行緒語言,但有沒有想過JavaScript為什麼是單執行緒語言,而不採用效率更高的多執行緒呢?並且一個單執行緒語言又是如何能夠實現非同步操作的呢?接下來我們詳細討論JavaScript的單執行緒和非同步實現(注:理論層面的實現,非語言層面)。

1、 JavaScript的單執行緒

眾所周知,JavaScript是單執行緒語言,試想一下,如果面試官問你JavaScript為什麼是單執行緒,你會怎樣回答?

我們首先要知道JavaScript是瀏覽器指令碼語言,是用來和使用者互動並且操作DOM的。試想一個場景,有兩個執行緒,一個執行緒向DOM節點中新增內容,另一個執行緒將此節點刪除,這樣就會導致很多不可預測的事情。所以,JavaScript的用途也就是應用場景決定了它必須是單執行緒。

在HTML5中,為了利用多核cpu的計算能力,提出了新的標準,允許JavaScript指令碼建立多個執行緒,但是子執行緒必須受主執行緒的控制,並且不得操作DOM,所以這個標準並沒有改變JavaScript是單執行緒的本質。

2、 JavaScript的非同步實現

首先我們要明白,為什麼需要非同步。

所謂單執行緒,就必然意味著:所有任務需要排隊,前一個任務結束,才會執行後一個任務。如果前一個任務耗時很長,後一個任務就不得不一直等著。然而排隊往往不是因為我們的CPU計算能力不行(如果是,我們也只好認了),大多數情況下,CPU處於空閒狀態,而IO操作是非常慢的一件事情(比如網路請求,定時器和事件監聽等等),我們不得不等到結果出來才能執行下一個任務。

可能有很多朋友到這裡就迷惑了,既然JavaScript是單執行緒語言,他怎麼能夠實現非同步呢?這是因為JavaScript的單執行緒是負責JavaScript解釋執行的引擎主執行緒是單執行緒的單執行緒和非同步不可能同時成為一個語言的特點),但是JavaScript所依賴的宿主環境(比如瀏覽器,node等)是多執行緒的,這些宿主環境通過某種方式使得JavaScript擁有了非同步的屬性。

當我們不需要等待IO裝置結果返回時,瀏覽器的主要執行緒完全可以不管IO裝置,掛起處於等待中的任務,先執行排在後面的任務。等到IO裝置返回了結果,再回過頭,把掛起的任務繼續執行下去,這樣就實現了非同步操作。

強調:JavaScript是單執行緒,是指JavaScript引擎是單執行緒執行的,瀏覽器無論在什麼時候都只且只有一個執行緒在執行JavaScript程式。但實現JavaScript的環境是多執行緒的,以瀏覽器為例,瀏覽器為這些耗時任務開闢了另外的執行緒,主要包括http請求執行緒,瀏覽器定時觸發器,瀏覽器事件觸發執行緒,這些任務是非同步的。

結語

此篇比較偏理論,後續會寫一些關於JavaScript的事件輪詢機制,以及如何用JavaScript實現非同步等文章來幫助大家理解JavaScript。

希望能夠解決大家工作和學習中的一些疑問,避免不必要的時間浪費,有不嚴謹的地方,也請大家批評指正,共同進步!
轉載請註明出處,謝謝!
交流方式:QQ1670765991