Node.js分享

image.png

1. 我們身邊的Node.js

以前 html+css+js 寫(xiě)前端頁(yè)面的時(shí)候,NodeJs基本上用不到,現(xiàn)在前端都是工程化了,我們一般都是腳手架搭建工程,通常會(huì)在本地開(kāi)啟一個(gè)服務(wù)器,例如vue-cli(npm run serve -> vue-cli-service serve -> webpack-dev-server -> express -> node -> http),本質(zhì)是 node 調(diào)用 http 模塊啟用了一個(gè)web服務(wù)器;再比如我們經(jīng)常用到的 npm(node package manager),這些都與NodeJs息息相關(guān)。

2. Node.js 是什么?

官網(wǎng)解釋:Node.js 是一個(gè)基于 Chrome V8 引擎的 JavaScript 運(yùn)行時(shí)。
個(gè)人理解:它并不是一門(mén)新的語(yǔ)言,本質(zhì)是一個(gè)環(huán)境,能夠讓 JavaScript 獨(dú)立運(yùn)行的這么一個(gè)環(huán)境,將前端開(kāi)發(fā)帶入到了服務(wù)器領(lǐng)域,底層由 C/C++ 開(kāi)發(fā)。
下面是一些關(guān)于 Node.js 的介紹
先看一張大致的結(jié)構(gòu)圖:

image.png

Node.js 發(fā)布于2009年5月,由 Ryan Dahl 開(kāi)發(fā),實(shí)質(zhì)是對(duì) V8 引擎進(jìn)行了封裝, V8 引擎是目前速度最快的 Javascript引擎,chrome瀏覽器就是用的V8解析javascript,在Node中,同樣也采用了V8解析javascript。 libuv 和一些其他庫(kù)拓展了js在前端沒(méi)有實(shí)現(xiàn)的功能,libuv是nodejs的底層支撐,包括事件循環(huán),文件IO,網(wǎng)絡(luò)IO,定時(shí)器等實(shí)現(xiàn)。代碼的結(jié)構(gòu)是(從上往下)nodejs內(nèi)置js模塊,比如http,net,fs,然后內(nèi)置的js模塊是調(diào)用c++層的代碼,比如net模塊調(diào)用tcp_wrap.cc,然后c++層調(diào)用libuv層的代碼,libuv完成任務(wù)后,再往回調(diào)。

特點(diǎn)

  1. 部署簡(jiǎn)單方便
  2. 事件驅(qū)動(dòng)
  3. 單線程(參考鏈接:Node.js真的是單線程嗎?
  4. 異步
  5. 非阻塞 I/O

3. Node.js 能做什么?

設(shè)想這么一個(gè)場(chǎng)景:我們?cè)诓蛷d排隊(duì)點(diǎn)餐,一種排隊(duì)方式是多條隊(duì)伍點(diǎn)餐(多線程,每個(gè)線程需要分配內(nèi)存),每個(gè)客戶需要在那等著廚師做好菜才到下一個(gè)客戶(同步阻塞),這個(gè)方法無(wú)疑會(huì)增加店內(nèi)的人力資源消耗(需要維護(hù)每個(gè)連接,增加了內(nèi)存開(kāi)銷(xiāo));另一種方式是只有一條隊(duì)伍(單線程,減少了內(nèi)存開(kāi)銷(xiāo)),但是我們點(diǎn)完餐后拿到了一個(gè)號(hào)碼,拿到號(hào)碼,我們往往會(huì)在位置上等待,而在我們后面的請(qǐng)求會(huì)繼續(xù)得到處理,收銀員能一直進(jìn)行處理(非阻塞)。

等到飯菜做好了,會(huì)喊號(hào)碼,我們拿到了自己的飯菜,進(jìn)行后續(xù)的處理(吃飯)。這個(gè)喊號(hào)碼的動(dòng)作在NodeJS中叫做回調(diào)(Callback),能在事件(燒菜,I/O)處理完成后繼續(xù)執(zhí)行后面的邏輯(吃飯),這體現(xiàn)了NodeJS的顯著特點(diǎn),異步機(jī)制、事件驅(qū)動(dòng)整個(gè)過(guò)程沒(méi)有阻塞新用戶的連接(點(diǎn)餐),也不需要維護(hù)已經(jīng)點(diǎn)餐的用戶與廚師的連接。

基于這樣的機(jī)制,理論上陸續(xù)有用戶請(qǐng)求連接,NodeJS都可以進(jìn)行響應(yīng),因此NodeJS能支持比Java、PHP程序更高的并發(fā)量,雖然維護(hù)事件隊(duì)列也需要成本,再由于NodeJS是單線程,事件隊(duì)列越長(zhǎng),得到響應(yīng)的時(shí)間就越長(zhǎng),并發(fā)量上去還是會(huì)力不從心。

單線程為什么能夠?qū)崿F(xiàn)高并發(fā)?參考:Nodejs探秘:深入理解單線程實(shí)現(xiàn)高并發(fā)原理

4. Node.js部分內(nèi)置模塊

  • os:
    os 模塊提供了與操作系統(tǒng)相關(guān)的實(shí)用方法和屬性
  • process:
    process 對(duì)象是一個(gè)全局變量,提供了有關(guān)當(dāng)前 Node.js 進(jìn)程的信息并對(duì)其進(jìn)行控制。 作為全局變量,它始終可供 Node.js 應(yīng)用程序使用,無(wú)需使用 require() 。 它也可以使用 require() 顯式地訪問(wèn):
const process = require('process');
  • fs:
    fs 模塊可用于與文件系統(tǒng)進(jìn)行交互。
    要使用此模塊:
const fs = require('fs');

所有的文件系統(tǒng)操作都具有同步的、回調(diào)的、以及基于 promise 的形式。

  • stream:
    流(stream)是 Node.js 中處理流式數(shù)據(jù)的抽象接口。 stream 模塊用于構(gòu)建實(shí)現(xiàn)了流接口的對(duì)象。
    Node.js 提供了多種流對(duì)象。 例如,HTTP 服務(wù)器的請(qǐng)求process.stdout 都是流的實(shí)例。
    流可以是可讀的、可寫(xiě)的、或者可讀可寫(xiě)的。
    nodeJS中的流最大的作用是:讀取大文件的過(guò)程中,不會(huì)一次性的讀入到內(nèi)存中。每次只會(huì)讀取數(shù)據(jù)源的一個(gè)數(shù)據(jù)塊。
    然后后續(xù)過(guò)程中可以立即處理該數(shù)據(jù)塊(數(shù)據(jù)處理完成后會(huì)進(jìn)入垃圾回收機(jī)制)。而不用等待所有的數(shù)據(jù)。
    訪問(wèn) stream 模塊:
const stream = require('stream');

盡管理解流的工作方式很重要,但是 stream 模塊主要用于開(kāi)發(fā)者創(chuàng)建新類(lèi)型的流實(shí)例。 對(duì)于以消費(fèi)流對(duì)象為主的開(kāi)發(fā)者,極少需要直接使用 stream 模塊。

const net = require('net');
net.createConnection(); // 別名 net.connect(); 客戶端創(chuàng)建連接
net.createServer(); 創(chuàng)建服務(wù)器
  • http、http2、https:
    若要使用 HTTP 服務(wù)器和客戶端,則可以 require('http') 。
    Node.js 中的 HTTP 接口旨在支持許多傳統(tǒng)上難以使用的協(xié)議的特性。 特別是,大塊的(且可能是塊編碼的)消息。 接口永遠(yuǎn)不會(huì)緩沖整個(gè)請(qǐng)求或響應(yīng),所以用戶可以流式地傳輸數(shù)據(jù)。

5. Express框架

基于 Node.js 平臺(tái),快速、開(kāi)放、極簡(jiǎn)的 Web 開(kāi)發(fā)框架

6. 使用Node.js + Express + Mysql 實(shí)現(xiàn)簡(jiǎn)單的登錄注冊(cè)

詳見(jiàn)附件demo
注意:(使用pm2[https://www.cnblogs.com/panpanwelcome/p/12720384.html], pm2 list, pm2 monit, 啟動(dòng): pm2 start xxx.js[id] --watch[監(jiān)控文件改變并且重啟應(yīng)用],
pm2 stop all/name/id, pm2 delete xxx.js[id])。
pm2 serve <path> <--name xxx> <--watch> <port>(開(kāi)啟一個(gè)文件服務(wù)器)

NodeJS服務(wù)總是崩潰的解決辦法:參考https://www.pianshen.com/article/2219160701/

7. Node.js使用場(chǎng)景

參考鏈接:有了Node.js,我們是不是可以放棄其他服務(wù)器語(yǔ)言?

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

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

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