做者:Piero Borrelliphp
翻譯:瘋狂的技術宅前端
原文:blog.logrocket.com/a-complete-…node
未經容許嚴禁轉載web
每當我聽到人們談論Node.js時,就會出現不少關於到底是什麼,這項技術有什麼用處,以及其將來的問題。npm
讓咱們試着解決第一部分。回答這個問題最簡單的方法是列出許多 Node 技術上的定義:前端工程化
可是,這些答案並不能令我滿意,由於有些東西不見了。在讀了上面的要點後,你可能會認爲 Node.js 只是另外一種 JavaScript 技術,可是若是你想要真正的理解它,最重要的是分析它是如何進行異步操做的和它的非阻塞 I/O 系統。異步
這是每一個 Web 開發人員應該必備的知識。ide
準確的理解 Node 在幕後的工做原理,不只會對這項技術瞭解的更多,還可以激發那些剛剛開始學習但還沒深刻使用的人們的興趣。函數
對於已是該領域的專業人士來講,瞭解它的內部和外部將使你成爲一個全新、前沿的開發人員,能夠根據你的需求去提升其性能。工具
所以,爲了挖掘 Node 的世界,咱們將檢視其核心部分:事件循環,實際上它是負責其非阻塞 I/O 模型的部分。
在深刻了解事件循環以前,我想先在線程上花一些時間。若是你想知道這樣作的必要性,我會告訴你是爲了更好地理解一個概念,咱們必須先在本身的腦海中造成一個術語表,這將有助於咱們識別系統的每個部分。咱們會在稍後閱讀有關事件循環如何工做,以及如何將線程的概念應用於它的內容時,這最終將具備很大的優點。
每當咱們運行一個程序時,就會爲它建立一個實例,而且有一些內部調用線程與該實例相關。線程能夠看做是咱們的 CPU 必須執行的操做單元。許多不一樣的線程能夠與程序的單個進程相關聯。下面這個圖能夠幫你在腦海中造成這個想法:
線程的簡圖
在討論線程時最重要的一點是:咱們的機器如何肯定在何時處理哪一個線程?
衆所周知,咱們機器的資源是有限的(CPU,RAM),所以正確的決定怎樣分配它們是很是重要,換一種說法是,哪些操做優先於其餘操做。這必需要作到,同時還要確操做不能消耗太多的時間 —— 沒有人喜歡運行速度慢的電腦。
用於解決分配問題的機制稱爲 scheduling,它由操做系統中的調度程序管理。這背後的邏輯可能很是複雜,但總而言之,咱們能夠將執行此操做的兩種主要方式組合在一塊兒:
多核機器如何處理線程
如今咱們已經對線程如何工做有了基本的瞭解,接下來解決 Node.js 事件循環邏輯。經過本文,你將瞭解前面那些解釋背後的緣由,每一條都會對應到正確的位置上。
每當運行 Node 程序時,都會自動建立一個線程。這個線程是整個代碼惟一執行的地方。在其中生成了一個被稱爲事件循環的東西。這個循環的做用是安排咱們惟一的線程應該在什麼時間點執行哪些操做。
如今讓咱們嘗試模擬事件循環的工做原理及其工做方式。首先假設咱們正在用名爲 myProgram
的文件爲 Node 提供信息,而後詳細瞭解事件循環將對其進行的操做。
特別是,我將首用一個簡短的圖來解釋,說明在事件循環 tick 過程當中發生的事情,而後再以更深刻的方式探討這些階段。
不該該單純的認爲事件循環其實是一個循環。它有一個特定的條件,用來肯定循環是否須要再次迭代。事件循環的每次迭代都被稱爲一個 tick。
每當執行程序時,咱們都會進行一系列須要執行的操做。這些操做主要分爲三種類型:
setTimeout()
,setInterval()
,setImmediate()
)我稍後會詳細介紹這些內容;如今讓咱們記住,只要其中一個操做處於掛起狀態,事件循環就會執行一個新的 tick。
對於每一個循環迭代,能夠分爲如下階段:
setTimeout()
和 setInterval()
的回調函數是否準備好在計時器過時的狀況下被調用。setImmediate()
函數相關函數。這是對 Node.js 的一種很是廣泛的誤解。 Node 運行在單個線程上,可是 Node.js 標準庫中包含的一些函數並非(例如 fs
模塊函數),他們的邏輯運行在 Node.js 線程以外。這樣作是爲了保證程序的速度和性能。
Node.js 會使用名爲 libuv 的特殊庫模塊來執行異步操做。此庫還與 Node 的後臺邏輯一塊兒使用,用來管理被稱爲 libuv 線程池 的特殊線程池。
這個線程池由四個線程組成,用於委派對事件循環來講過重的操做。長時間運行的任務對於事件循環而言代價過於昂貴。
從這個意義上說,雖然在上述過程當中涉及一些相似棧的結構,但更精確的答案是事件循環由一系列的階段所組成,每一個階段都有本身的特定任務,全部階段都以循環重複的方式去處理。若是想要知道關於事件循環確切結構的更多信息,請查看此演講。
瞭解事件循環是使用 Node.js 的重要部分,不管你是想得到有關此技術的更多看法,瞭解如何提升其性能,仍是找到學習新工具理由。