1. 程式人生 > >【JavaScript】JavaScript是多執行緒還是單執行緒?

【JavaScript】JavaScript是多執行緒還是單執行緒?

  之前在學瀏覽器渲染流程時瞭解的JavaScript是單執行緒執行的,時不時要考慮瀏覽器執行緒阻塞問題,然而又有人說JavaScript可以非同步執行,比如setInterval、setTimeout以及Ajax等。那究竟是單執行緒還是多執行緒呢?
  下圖是瀏覽器所具有的執行緒:
  這裡寫圖片描述

單執行緒意味著,所有任務需要排隊,前一個任務結束,才會執行後一個任務。如果前一個任務耗時很長,後一個任務就不得不一直等著。於是就有這麼一個概念——任務佇列。

  首先我闡明下JavaScript是門同步的語言,上面我們通常所說的JavaScript的非同步與其他語言的非同步是不相同的,本質上還是同步

。因為瀏覽器會有多個Queue存放非同步通知,並且每個Queue的優先順序也不同。JavaScript在執行程式碼時會產生一個執行棧,同步的程式碼在執行棧中,非同步的在Queue中。有一個Event Loop會迴圈檢查執行棧是否為空,為空時會在Queue中檢視是否有需要處理的通知,有的話拿到執行棧中去執行。

  JavaScript語言的設計者意識到,這時主執行緒完全可以不管IO裝置,掛起處於等待中的任務,先執行排在後面的任務,等到IO裝置返回了結果,再回過頭,把掛起的任務繼續執行下去。
  於是,所有任務可以分為兩種:一種是同步任務,一種是非同步任務。
  同步任務是指在主執行緒上排隊執行的任務,只有前一個任務執行完畢,才能執行後一個任務;非同步任務是指不進入主執行緒,而進入“任務佇列”的任務,只有“任務佇列”通知主執行緒,某個非同步任務可以執行了,該任務才會進入主執行緒執行。

  在HTML5之前,瀏覽器中的JavaScript的執行都是以單執行緒的方式工作的。雖然有多種方式實現了對多執行緒的模擬(例如:JavaScript中的setInterval方法,setTimeout方法等),但是在本質上程式的執行仍然是由JavaScript引擎以單執行緒排程的方式進行的。
  在HTML5中引入的Web Worker使得瀏覽器端的JavaScript引擎可以併發地執行JavaScript程式碼,從而實現了對瀏覽器端多執行緒的良好支援。
  所以,JavaScript是門單執行緒的語言,而其多執行緒的表現是屬於瀏覽器的行為(JS引擎),他們之間沒有衝突,更不是同一種事物。