到底什么是 Node.js

Node.js 是一個 JavaScript 運(yùn)行時環(huán)境。聽起來不錯,但這意味著什么?這是如何運(yùn)作的?

Node 運(yùn)行時環(huán)境包含著執(zhí)行 JavaScript 所編寫的程序所需的一切。

Java和Node.js對比

當(dāng) JavaScript 的開發(fā)者,將 JavaScript 從瀏覽器開發(fā)拓展到本地計算機(jī)上開發(fā)時,Node.js 就出現(xiàn)了。

現(xiàn)在,您可以使用 JavaScript 做更多事情,而不僅僅是讓網(wǎng)站可以互動。

JavaScript 現(xiàn)在能夠執(zhí)行其他腳本語言(如 Python)可以執(zhí)行的操作。

瀏覽器的 JavaScript 和 Node.js 都在 V8 JavaScript 運(yùn)行時引擎上運(yùn)行。該引擎將 JavaScript 代碼轉(zhuǎn)換為更快的機(jī)器代碼。機(jī)器代碼是低級代碼,計算機(jī)可以直接運(yùn)行。

為什么選擇 Node.js

這是官方 Node.js 網(wǎng)站上給出的正式定義:

Node.js? 是基于 Chrome 的 V8 JavaScript 引擎構(gòu)建的 JavaScript 運(yùn)行時。
Node.js 使用事件驅(qū)動的非阻塞 I/O 模型,使其輕量且高效。
Node.js 的包生態(tài)系統(tǒng),npm,是世界上最大的開源庫生態(tài)系統(tǒng)。

我們已經(jīng)討論過這個定義的第一行:“Node.js? 是一個基于 Chrome 的 V8 JavaScript 引擎構(gòu)建的 JavaScript 運(yùn)行時?!爆F(xiàn)在讓我們了解其他兩行,這樣我們就可以找出為什么 Node.js 如此受歡迎。

I/O 指的是輸入/輸出。它可以是從讀取/寫入本地文件到發(fā)出 HTTP 請求到 API 的任何內(nèi)容。

I/O 需要時間,因此會阻塞其他方法的執(zhí)行。

考慮一種情況,我們請求后端數(shù)據(jù)庫獲取 user1 和 user2 的詳細(xì)信息,然后在屏幕/控制臺上打印它們。對該請求的響應(yīng)需要時間,但是兩個用戶數(shù)據(jù)請求可以獨(dú)立地同時執(zhí)行。

阻塞I/O和非阻塞I/O對比

阻塞 I/O

在阻塞方法中,在 user1 的數(shù)據(jù)打印到屏幕之前,不會啟動 user2 的數(shù)據(jù)請求。

如果這是一個 Web 服務(wù)器,我們必須為每個新用戶啟動一個新線程。但 JavaScript 是單線程的(不是真的,但它有一個單線程的事件循環(huán),我們稍后會討論)。所以這會使 JavaScript 不太適合多線程任務(wù)。

這就是非阻塞章節(jié)的用武之地。

非阻塞 I/O

另一方面,使用非阻塞請求,您可以為 user2 發(fā)起數(shù)據(jù)請求,而無需等待對 user1 請求的響應(yīng)。您可以并行啟動這兩個請求。

這種非阻塞 I/O 消除了對多線程的需要,因?yàn)榉?wù)器可以同時處理多個請求。

JavaScript 事件循環(huán)

如果您有 26 分鐘,請觀看 node.js 事件循環(huán)的優(yōu)秀視頻說明
沒有的話,這里是 JavaScript 事件循環(huán)如何工作的快速逐步說明。

event-loop.png
  1. 將 main()方法推入調(diào)用堆棧。
  2. 將 console.log()方法推送到調(diào)用堆棧。然后立即運(yùn)行并彈出。
  3. 將 setTimeout(2000)推入堆棧。 setTimeout(2000)是一個 Node API。當(dāng)我們調(diào)用它時,我們注冊事件回調(diào)對。該事件將等待 2000 毫秒,然后回調(diào)就是該函數(shù)。
  4. 在 API 中注冊后,setTimeout(2000)將從調(diào)用堆棧中彈出。
  5. 現(xiàn)在第二個 setTimeout(0)以相同的方式注冊。我們現(xiàn)在有兩個 Node API 等待執(zhí)行。
  6. 等待 0 秒后,setTimeout(0)被移動到回調(diào)隊(duì)列,并且 setTimeout(2000)也會發(fā)生同樣的事情。
  7. 在回調(diào)隊(duì)列中,函數(shù)等待調(diào)用堆棧為空,因?yàn)橹挥幸粋€語句可以執(zhí)行一次。這由事件循環(huán)處理。
  8. 最后一個 console.log()運(yùn)行,main()從調(diào)用堆棧中彈出。
  9. 事件循環(huán)看到調(diào)用堆棧為空并且回調(diào)隊(duì)列不為空。因此,它將回調(diào)(以先進(jìn)先出順序)移動到調(diào)用堆棧以執(zhí)行。

npm

npm.png

這些是由令人敬畏的社區(qū)構(gòu)建的庫,它將解決大多數(shù)常規(guī)問題。 npm(node 的包管理工具)具有可在應(yīng)用程序中使用的包,以使開發(fā)更快更有效。

Require

Require 做了三件事情:

  • 它從 Node.js API 加載與 Node.js 捆綁在一起的模塊,如文件系統(tǒng)和 HTTP。
  • 它加載從 npm 安裝的第三方庫,如 Express 和 Mongoose。
  • 它加載您自己的文件并模塊化項(xiàng)目。

Require 是一個方法,它將“path”作為參數(shù),返回module.exports

Node Modules

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

您可以編寫自己的模塊并在各種應(yīng)用程序中使用它。 Node.js 有一組內(nèi)置模塊,無需進(jìn)一步安裝即可使用。

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

V8 是一個用 C++編寫的開源運(yùn)行時引擎。

JavaScript -> V8(C++) -> Machine Code

V8 實(shí)現(xiàn)了 ECMA-262 中指定的名為 ECMAScript 的腳本。 ECMAScript 由 Ecma International 創(chuàng)建,用于標(biāo)準(zhǔn)化 JavaScript。

V8 可以獨(dú)立運(yùn)行,也可以嵌入到任何 C++應(yīng)用程序中。它有一些鉤子,允許您編寫自己的 C++代碼,以供 JavaScript 使用。

這實(shí)際上允許您通過將 V8 嵌入到 C++代碼中來向 JavaScript 添加功能,以便您的 C++代碼比 ECMAScript 標(biāo)準(zhǔn)另外指定的更多。

事件

在我們的應(yīng)用程序中發(fā)生的事情,我們可以回應(yīng)。 Node 中有兩種類型的事件。

  • 系統(tǒng)事件:來自名為 libuv 的庫的 C++核心。 (例如,讀完文件)
  • 自定義事件:JavaScript 核心。

用 Node.js 寫 Hello World

這是我們必須做的~

創(chuàng)建一個app.js的文件,文件中加上下列語句:

console.log("Hello World!");

打開node的終端,將目錄更改為保存文件的文件夾,然后運(yùn)行node app.js。

您可以使用大量資源了解有關(guān)Node.js的更多信息,包括freeCodeCamp.org。

注:本篇文章為譯文,原文鏈接

前往我的個人博客可以查看更多精彩文章 :)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容