js是單線程的,為什麼可以執行非同步操作呢? 這歸結與瀏覽器(js的宿主環境)通過某種方式使得js具備了非同步的屬性。 區分進程和線程: 進程:正在運行中的應用程式。每個進程都自己獨立的記憶體空間。例如:打開的瀏覽器就是一個進程。 線程:進程的子集,是獨立的。線程在共用的記憶體空間中運行。 瀏覽器是多進程的 ...
js是單線程的,為什麼可以執行非同步操作呢?
這歸結與瀏覽器(js的宿主環境)通過某種方式使得js具備了非同步的屬性。
區分進程和線程:
進程:正在運行中的應用程式。每個進程都自己獨立的記憶體空間。例如:打開的瀏覽器就是一個進程。
線程:進程的子集,是獨立的。線程在共用的記憶體空間中運行。
瀏覽器是多進程的。如下圖:
並且每打開一個頁面就創建了一個獨立的進程。進程內有自己的多線程。如果瀏覽器是單進程的,那麼某個頁面崩了,就會影響整個瀏覽器。
瀏覽器有哪些進程:
1.Browser(瀏覽器):瀏覽器的主進程(負責協調,主控)只有一個,作用有:- 負責瀏覽器界面顯示,與用戶交互。如前進,後退等
- 負責各個頁面的管理,創建和銷毀其他進程
- 將Renderer(渲染器)進程得到的記憶體中的Bitmap,繪製到用戶界面上
- 網路資源的管理,下載等
GUI渲染線程與JS引擎線程互斥: 由於JavaScript是可操縱DOM的,如果在修改這些元素屬性同時渲染界面(即JS線程和UI線程同時運行),那麼渲染線程前後獲得的元素數據就可能不一致了。因此為了防止渲染出現不可預期的結果,瀏覽器設置GUI渲染線程與JS引擎為互斥的關係,當JS引擎執行時GUI線程會被掛起,GUI更新則會被保存在一個隊列中等到JS引擎線程空閑時立即被執行。 js執行機制:js是單線程的,每當執行函數就把函數推入棧中,但有非同步的操作就讓瀏覽器的線程(webAPI)去處理,處理完放到任務隊列里,當主線程(執行棧)執行完畢時,如果任務隊列里有任務,就執行。
這也就是為什麼下麵代碼會先輸出b,然後是a的原因。settimeout的函數會放到任務隊列中,而console.log('b')是主線程。
setTimeout(() => {
console.log('a');
}, 0);
console.log('b');