Node.js 到底是什麼?

翻譯:瘋狂的技術宅javascript

medium.freecodecamp.org/the-definit…前端

聲明:未經容許,嚴禁轉載java

Node.js 是一個 JavaScript 運行時環境。聽起來還不錯,不過這究竟意味着什麼?它又是如何運做的?node

Node 運行時環境包含執行 JavaScript 程序所須要的一切。數據庫

img

若是你瞭解 Java 的話,會發現它們有點像。npm

JavaScript 原來是隻能在瀏覽器中運行的,當把它擴展成爲能夠在你的計算機上做爲獨立的程序運行時,Node.js 就出現了。後端

如今你能夠用 JavaScript 作更多的事情,而不只僅是用在網站的互動和特效上。前端工程化

JavaScript 如今可以去作其餘腳本語言(如Python)能夠執行的操做。api

你 Chrome 瀏覽器中的 JavaScript 和 Node.js 都在 V8 引擎上運行。該引擎將你的 JavaScript 代碼轉換爲更快的機器代碼。機器代碼是低級代碼,計算機能夠直接運行而無需先解釋它。瀏覽器

爲何選擇 Node.js?

這是 Node.js 官方網站上給出的正式定義:

Node.js®是基於 Chrome 的 V8 JavaScript 引擎構建的 JavaScript 運行時環境。

Node.js 使用事件驅動的非阻塞 I/O模型,輕量且高效。

Node.js 的包生態系統 npm 是世界上最大的開源庫生態系統。

咱們在前面已經討論過了這個定義的第一行:「Node.js®是基於 Chrome 的 V8 JavaScript 引擎構建的 JavaScript 運行時環境。」 如今讓咱們理解剩下的兩行,這樣咱們就能夠找出爲何 Node.js 如此受歡迎的緣由。

I/O 指的是輸入/輸出。它能夠是從讀取/寫入本地文件到向 API 發出 HTTP 的任何內容。

I/O 須要時間,所以會阻止其餘函數。

考慮一下這種狀況,咱們須要經過請求後端數據庫來獲取 user1 和 user2 的詳細信息,而後在屏幕或控制檯上打印它們。對該請求的響應須要時間,可是兩個用戶數據的請求能夠獨立地同時執行。

阻塞 I/O(左)與非阻塞 I/O(右)

阻塞 I/O(左)與非阻塞 I/O(右)

阻塞 I/O

在阻塞方法中,在 user1 的數據被輸出到屏幕以前,不會啓動 user2 的數據請求。

若是這是一個Web服務器,咱們必須爲每一個新用戶啓動一個新線程。但 JavaScript 是單線程的(實際上不是真的,但它有一個單線程的事件循環,咱們稍後會討論)。因此這會使 JavaScript 不太適合多線程任務。

這就是非阻塞的用武之地。

非阻塞 I/O

另外一方面,若是用非阻塞請求,能夠在爲 user2 發起數據請求時,無需先等待對 user1 請求的響應。你能夠並行啓動這兩個請求。

這種非阻塞 I/O 消除了對多線程的須要,由於服務器能夠同時處理多個請求。

JavaScript 事件循環

如下是 JavaScript 事件循環工做原理簡要的逐步描述。

img

  1. main() 送入調用棧。
  2. console.log() 送入調用棧。而後當即運行並彈出。
  3. setTimeout(2000) 送入棧。 setTimeout(2000)是一個 Node API。在調用它時,先註冊事件回調。事件將等待 2000 毫秒,而後回調這個函數。
  4. 在 API 中註冊後,setTimeout(2000) 從調用堆棧中彈出。
  5. 如今第二個 setTimeout(0) 以相同的方式註冊。咱們如今有兩個 Node API 等待執行。
  6. 等待 0 秒後,setTimeout(0) 被移動到回調隊列,一樣的事情發生在 setTimeout(2000)
  7. 在回調隊列中,函數等待調用棧爲空,由於每一個語句都執行一次。這由事件循環處理。
  8. 最後一個 console.log() 運行,而且 main() 從調用棧中彈出。
  9. 若是事件循環檢測到到調用堆棧爲空且回調隊列不爲空。它將回調(以先進先出順序)移動到調用棧並執行。

npm

img

這些是由使人敬畏的社區所構建的庫,它能解決你的大多數的常規問題。 npm(Node package manager))中有不少能夠用在你的程序中包,可使你的開發更快更有效。

Require

Require 作三件事:

  • 它從 Node.js API 加載與 Node.js 捆綁在一塊兒的模塊,如文件系統和 HTTP 等。
  • 它加載從 npm 安裝的第三方庫,如 Express 和 Mongoose 等。
  • 它容許你 require 本身的文件並把項目模塊化。

Require 是一個函數,它接受參數 「path」 並返回 module.exports

Node 模塊

Node 模塊是一個可重用的代碼塊,它的存在不會對其餘代碼產生意外地影響。

你能夠編寫本身的模塊並在各類程序中使用它。 Node.js 有一組內置模塊,無需進一步安裝便可使用。

V8 經過利用 C++ 來加速 JavaScript

V8 是一個用 C++ 編寫的開源運行時引擎。

JavaScript => V8(C ++)=> 機器碼

V8 實現了 ECMA-262 中指定的名爲 ECMAScript 的腳本。 ECMAScript 由 Ecma International 建立,用於標準化JavaScript。

V8 能夠獨立運行,也能夠嵌入到任何 C++ 程序中。它有一些鉤子,容許你編寫本身的C++代碼供 JavaScript 使用。

這實際上容許你經過將 V8 嵌入到 C++ 代碼中來向 JavaScript 添加功能,以便使你的 C++ 代碼實現比 ECMAScript 標準更多的功能。

正如 Greg Bulmash 引發了個人注意,除了V8以外,還有許多不一樣的 JavaScript 引擎,如 Mozilla 的 SpiderMonkey,微軟的 Chakra 等等。更多的東西能夠在這裏找到。

事件

事件指的是咱們能夠對在程序中發生的事情做出迴應。Node 中有兩種類型的事件。

  • 系統事件:來自用 C++ 實現的基於 libuv 庫的內核。(例如,讀取文件完畢)。
  • 自定義事件:JavaScript 核心。

在 Node.js 中寫一個 Hello World

建立文件 app.js 並將如下內容添加到其中。

console.log("Hello World!");
複製代碼

打開終端,將目錄切換到保存文件的文件夾,而後運行 node app.js

就這麼簡單,你在 Node.js 中寫的 「Hello World」 跑起來了。

最後,你能夠經過互聯網上的大量資源去了解關於 Node.js 的更多信息。

歡迎關注前端公衆號:前端先鋒,獲取前端工程化實用工具包。

相關文章
相關標籤/搜索