Js 的多宿主時代

之前有寫過一篇文章 Js運行機制深層剖析,主要講的是 Js 的事件循環機制 (Event Loop),從現在的眼光看來,不能說錯,但是也絕對談不上“深層”(誰還沒年輕過呢),在 Js 多宿主時代的今天,有必要站在一個更高的角度來進行左右互搏

一、宿主的歸宿主 Js 的歸 Js

這里的宿主指的是,js 的運行環境,目前 js 的主流運行環境有瀏覽器、Node 以及 RN/Weex

Js運行機制深層剖析 這篇文章對事件循環機制的敘述基本是清楚的,但是并沒有剝離出 Js 本身合宿主的部分。在此之前,我們對 Js 的討論多是(默認)基于瀏覽器,不剝離似乎也不會有什么影響,時至今日,倘若要將我們的 Js 能力擴展到后臺 Node、RN/Weex 端,剝離對待,將會給你一種一切盡在掌握的既視感

以各個宿主環境的基本組成元件的對比作為切入點


瀏覽器與 Node 對比
RN/Weex

在我最近的兩篇文章中,都有提及對三個宿主環境的對比(可能還更為詳盡),從本文的行文有利的角度可以總結如下:

多個宿主都包含一個 javascript 引擎用于執行 js,其中以 v8 運用得最為廣泛,并且都通過一個中間層讀取 IO,在前端(瀏覽器/RN/Weex)還包含一個界面渲染引擎
也就是說,Js 的基礎語言能力,主要由 Js 引擎支撐(v8/javascriptCore 等),例如數組、函數、對象等基本語法;而 IO 的讀寫,界面的渲染 Api,都屬于宿主的擴展,由宿主統一協調調度

舉個例子,在瀏覽器中,Js 可以調用 Dom Api 來操作 Html Dom,從而影響渲染樹,這其實是瀏覽器對 Js 擴展出來的 Api,并通過中間層來協調 Js 引擎和渲染內核之間的通訊;瀏覽器的 window 對象如是,它的 location、history 等接口都是宿主為了讓 Js 可以操縱瀏覽器外殼行為的一種擴展,要知道在 Node 當中,就沒有 Dom Api 和 window 對象,因為 Node 作為后端的宿主,壓根就沒有界面渲染引擎

對于宿主外殼與 Js 引擎之間通訊,以 Node 為例,Node 環境由 c/c++ 編寫而來,其中嵌入了一個 Js 引擎 v8(當然 v8 也是用的 c/c++ 寫的),整一個通訊過程,就是 c++ 對 v8 的調用的過程。為了支撐 Js 的異步 IO 讀寫,宿主還會為其構筑一個事件循環以及線程池,這個后面說

二、IO 的讀寫

計算機可以被抽象為計算單元(CPU)和輸入輸出單元(IO),無論是瀏覽器、Node 還是 RN/Weex 都需要調度好 CPU 和 IO 的使用,以期最大程度的提高效能。如果將前端的渲染元件當做對顯卡的讀寫,那么各個宿主的區別其實又可以抽象到 IO 能力的支持上

Js 的 IO 讀寫能力依賴于宿主這個沙盒對它的擴展,瀏覽器擴展了 Dom Api 可以讓 Js 方便的操作渲染元件,而在對磁盤的讀寫上面,Node 卻比瀏覽器要方便許多;Node 可以控制網卡開啟一個 Http Server,而瀏覽器卻未提供此能力。真的,沒那么復雜

各個宿主之間的區別,主要體現在對 IO 讀寫能力擴展之上

無論是阻塞式的 IO 還是非阻塞式的 IO,都有一個線程等待的過程,每一秒的等待都是對 CPU 極大的浪費,所以幾乎所有的高級語言在對 IO 的讀取上,都會通過創建專門的監聽線程用于等待 IO 的讀取。然而,想必你一定聽說過,Js 是一門單線程語言,但是它的異步機制卻很好的解決了 IO 讀取的等待過程。其實,這個單線程只是指的是 Js 有唯一的用戶線程,也就是扔到 v8 里執行的那一段 Js 代碼是單線程的,而宿主環境,為了讓 Js 能在讀取 IO 的過程中能更有效率的利用 CPU,創建了線程池,采用事件循環機制從而支撐起了 Js 的異步能力,在這一點上,各個宿主之間殊途同歸~~

三、異步的實現機理

異步實現機理

Js運行機制深層剖析 那篇文章中也畫過類似的一個圖,這里只進行了一些小小的改動,圈出了線程池以及 Js 引擎部分(關于事件循環的內容,之前那篇文章的介紹可能更為詳盡,可以參考著看)

平時我們所說的 Js 是單線程的,指的是它只有一個唯一執行線程(用戶線程),也就是上圖右下角 Js 引擎的部分,但是從整個宿主層面來看,還需要維護一個線程池,每一次異步IO的調用,都會在線程池里找一個可用的線程,用于監聽并等待IO的讀取,并在IO讀取完成之后將回調函數壓入事件循環,Js 執行線程每次 pop 一個回調函數以及它的執行上下文進行執行

特別的,除了 IO 的讀取是異步的,定時函數(例如 setTimeout)也是異步的,需要通過計時線程來適時的將回調壓入事件循環,在 Js 執行線程執行完當前任務之后,再從事件循環中 pop 出來執行,所以 setTimeout 有時候并不一定那么準時

四、總結

技術上如果太給自己限定界限,畫地為牢,總會有一種只緣身在此山中的感覺,如果升華一下,站遠了看,或許看得會更為全面~~

菲麥前端 是一個讓知識深入原理的知識社群,我們有 知識星球、公眾號以及群,歡迎加微勾搭:facemagic2014

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容