當前位置:
首頁 > 知識 > 2分鐘看懂 Node.js 精髓

2分鐘看懂 Node.js 精髓

1、為什麼要學習Node.js?

Node.js是目前非常火熱的技術,可是作為一個前端開發人員,為什麼要學Node.js?

說Node.js優劣的文章,網上一大堆,在這兒就不過多描述了。技術是服務於業務的,學技術最終目的就是為了更高的收入,咱們就是這麼俗,那就從以下兩點來看看,為什麼要學Node.js

從工作上來說

首先第一點,很多大公司都在用Node.js,並且很多大廠的招聘「高級前端工程師」也明確提出了要掌握Node.js,所以學習Node.js成了我們前端開發者想要獲得高薪,繞不過去的坎。

從現在的招聘信息來看,全棧是一個大趨勢,兩個前端技術相同的人,如果其中一個人懂後端開發,那麼不管是他的薪酬待遇還是入職概率,都比另一個人要高的多。

當前端工程師了解服務端的開發之後,在與後台開發的溝通,將大大的提高溝通效率,從而提高開發效率。在這不得不說,公司真是個小機靈鬼。

所以,市場逼著我們這些前端開發者要學習服務端開發。

再從投入/回報上看

Node.js是基於JavaScript語言和V8引擎的Web伺服器項目,我們可以直接使用JavaScript來搭架伺服器。

快樂的是,作為前端開發,我們的看家本領就是JavaScript,學習Node簡直不要太輕鬆,這樣是大大的降低了我們學習後端開發的難度。

而且在Node環境下,通過模塊化的JavaScript代碼,加上函數式編程,並且無需考慮瀏覽器兼容性問題,直接使用最新的ECMAScript 6標準,可以完全滿足工程上的需求。

在Node.js中,模塊化,構建,輔助工具,調優,架構調整,這些東西是無處不在的。在Node環境中的編程思想,同時也能提高我們前端開發的質量,這樣相輔相成,讓我們能更快速的提高自己!

所以,學習Node無疑是快速掌握全棧技術的最好途徑

悄悄的告訴你,學Node.js還有一個很大的好處,就是能更清楚的知道,伺服器是怎麼運作的,所以就算是做後台的,學習Node.js也是妙不可言。

2、Node.js的特點

在說Node.js解決了什麼問題,如何解決痛點之前,有必要先說一下Node.js的特性

Node.js是一個Javascript運行環境

依賴於Chrome V8引擎進行代碼解釋

事件驅動

非阻塞I/O

輕量、可伸縮,適於實時數據交互應用

單進程,單線程

這些特點,不能一條一條的來看,而是要綜合起來一起看

我認為其中有個最重要的一點,那就是事件驅動。這也是為什麼Node.js採用JavaScript單線程語言,來做到非阻塞I/O,同時處理萬級的並發而不會造成I/O阻塞的原因。(後面會詳細說明)

其中V8引擎,是Node.js也是採用JavaScript的關鍵因素之一,因為它為JavaScript提供了在非瀏覽器運行環境,V8的高效也是導致Node.js高效的原因之一

3、Node.js解決了什麼問題?

了解了Node.js的特性,再來看Node.js解決了什麼問題,就更容易理解了

要學習一門新技術,那我們首先得知道他是要解決了什麼別人解決不了或者是難解決的問題

不然我們一股腦的學了之後,它是用來幹啥的都不知道,又怎麼會知道在什麼時候,應該選擇什麼樣的技術來更優雅的寫BUG呢?

Node.js主要解決了以下兩個頭疼的事情

並發連接

I/O阻塞

什麼是並發連接?有趣的例子

並發這東西,可是吹牛必備啊,想必大家應該都知道並發是個什麼玩意。但畢竟是入門文章,擔心有些人沒什麼印象,這裡還是簡單提一下。

並發(Concurrency): 是指在一個系統中,擁有多個計算,這些計算有同時執行的特性,而且他們之間有著潛在的交互。

看概念很難理解,其實並不複雜,比如「我們吃飯吃到一半,電話來了,我們停了下來接了電話,接完後繼續吃飯,這說明支持並發。」

用程序來解釋就是一群用戶同時來訪問我們的網站/程序。

一般我們在處理並發的時候,都是儘可能的做到讀寫分離,或者分散式部署不同的伺服器,或者直接簡短粗暴的提升我們單機伺服器的性能。

可這樣做要麼是苦逼了程序員,要麼就是苦逼了公司的錢包。

我要是公司老闆,能不出伺服器這個錢就肯定不出,畢竟不管是升級伺服器還是擴張伺服器,那都是一筆不小的錢啊。

那就只能苦逼一下員工了咯~可我們又不想這麼苦逼,這時候用Node.js就能幫我們省不少麻煩。

那Node.js又是怎樣處理高並發的呢?

在這裡容我先賣個關子,看完I/O阻塞之後,再來看看Node.js是怎樣處理的。

什麼是I/O阻塞?

先說說I/O是什麼

I/O是input/output(輸入/輸出)

知道I/O之後,接下來的阻塞就很容易理解了。

形象的說,我在餐廳吃飯,就這一個座位,我點完餐後,坐在這享受美食。

然而這時候來了個路人甲,點餐後想坐下吃飯,而這時候我還沒吃完呢,想讓我讓位置給你?不存在的

路人甲只能在旁邊眼巴巴的看著我吃。得等我吃完,走了之後,他才能坐下來吃飯。而這等待的過程呢,就可以叫做阻塞。

這樣做明顯非常不合理嘛

那Node.js是怎麼來解決I/O阻塞的呢?

Node.js遇到I/O事件,並不會先處理,而是先放在事件隊列中,主線程依然繼續往下執行,利用非同步操作來處理事件隊列中的事情。

作為一個乾貨文章,怎麼能少的了圖呢?沒圖你怎麼理解?

來看看從用戶請求到伺服器返回數據,Node.js為了應對並發,都做了些啥玩意

我想你現在肯定是懵逼的,那繼續剛才吃飯的例子從頭道來~~~

我跟路人甲同時進入餐館。老闆坐在板凳上等著客人光顧。

我跟路人甲同時找到老闆說「老闆!我要來一份雞腿!」,這時候老闆不樂意了,文明點餐,請取號排隊!

我跟路人甲先後取號坐好後(肯定是我拿的1號,路人甲拿的2號啦,畢竟主角光環在這頂著)

老闆喊來了服務員小A、小B

老闆吩咐「小A啊~去招待1號主角點餐入座點餐」

接著又吩咐「小B啊~去招待2號路人甲入座點餐」

吩咐完後,老闆繼續坐板凳上等著新的客人關顧……

此時小A、小B分別就帶著我跟路人甲去入座點餐

當我或者路人甲吃完飯結賬離開時,老闆都會對我們說「慢走~~~謝謝惠顧,下次再來!」

故事說完,咱們來按照故事解釋一下程序的運作

我跟路人甲就是用戶。

老闆,就是這個程序的主線程。

服務員小A,小B就是線程池裡的子線程。

我跟路人甲同時找到老闆點餐,這就是用戶的並發請求。

老闆管理整個餐廳的運作,發現我們的請求是I/O阻塞呀,所以讓我們排隊取號。這也就是Node.js中維護的事件隊列。

我們點餐之後的入座就餐還有上菜,這些I/O阻塞的事情,都是由服務員來提供服務,老闆並不參與其中。

在我們用餐完畢的時候,會通知老闆我們要結賬離開,結賬離開這個動作就是事件執行完畢後的一個回調函數。

此時老闆就會跟我們說「慢走~~~謝謝惠顧,下次再來!」,也就是事件執行完後回調函數的一個操作,並且將線程釋放回線程池。

現在再回過頭去看圖,是不是清晰的多了。

總結以下:

1、每個Node.js進程只有一個主線程在執行程序代碼。

2、當用戶的網路請求或者其它的非同步操作到來時,Node.js都會把它放到「事件隊列」之中,並不會立即執行它,代碼就不會被阻塞,主線程繼續往下走,直到主線程代碼執行完畢。

3、當主線程代碼執行完畢完成後,通過事件循環機制,從「事件隊列」的開頭取出一個事件,從線程池中分配一個線程去執行這個事件,接下來繼續取出第二個事件,再從線程池中分配一個線程去執行,一直執行到事件隊列的尾部。期間主線程不斷的檢查事件隊列中是否有未執行的事件,直到事件隊列中所有事件都執行完,此後每當有新的事件加入到事件隊列中,都會通知主線程按順序取出交代碼循環處理。當有事件執行完畢後,會通知主線程,主線程執行回調,線程歸還給線程池。

以Java、C#為例,在Java、C#中也有辦法實現並行請求(利用子線程),但NodeJS通過回調函數(Callback)和非同步機制,把I/O阻塞處理的更優雅(說人話就是用Code實現起來更簡單易懂,並且性能更好)。

說到這裡,你可能就會問

說好的Node.js是單線程的呢?那Node.js怎麼又創建子線程了呢?怎麼就跟Java、C#中的線程不一樣了呢?怎麼就更優雅了呢?

那就來解釋一波

Node.js使用非同步IO和事件驅動(回調函數)來解決這個問題。

一般來說,高並發解決方案會提供多線程模型,為每個業務邏輯提供一個線程,通過系統線程切換來來彌補同步I/O調用的時間開銷。

像PHP,是一個請求一個線程,假如一個線程需要2M內存,那麼同時有512個請求,就需要1G的內存,那同時有5120個請求,就需要10G內存,現在內存這麼貴的情況下,想想都恐怖。。。

而Node.js使用的是單線程模型,對所有I/O都採用非同步的請求方式,在Node.js執行的時候維護著一個事件隊列,程序在執行時進入事件循環等待下一個事件到來,每個非同步I/O請求完成後都會被推送到事件隊列中的等待執行。

Node.js是因為是基於JavaScript的特性,所以單線程的,但是,單線程只局限於JavaScript部分,Node.js核心還是用C/C++語言編寫的,文章開頭就說到過,它只是給JavaScript提供了一個運行環境而已,它是JavaScript語言的解釋器。

我們所看到的Node.js單線程只是一個js主線程,本質上的非同步操作還是由線程池完成的,Node.js將所有的阻塞操作都交給了內部的線程池去實現,本身只負責不斷的往返調度,並沒有進行真正的I/O操作,從而實現非同步非阻塞I/O,這便是Node.js單線程和事件驅動的精髓之處了。

所以它跟Java、PHP、C#這些後台語言的實現的線程不一樣的。

關於更優雅呢,主要就是實現起來更容易。比如說在Java、C#中實現多線程的時候,總是要注意線程安全,這裡要Lock,那裡也要Lock。

一個不注意就得加班熬夜好幾個通宵才能找出問題所在……

而Node.js卻是利用單線程執行,Node.js官方也是說不需要鎖。但是不需要鎖,不代表你可以亂來,不需要鎖的是代碼function,而不是你的資源! 這點要分清楚。

4、搭建我們第一個Node.js伺服器

看了這麼多基礎性的內容,枯燥、乏味,沒勁,看的想睡覺。

現在動手操作一波,刺激一下自己的腎上腺素,一起來搭建一個超簡單的Node.js伺服器

//引用http模塊

const http=require("http");

//創建一個服務

//request:伺服器接收的請求數據

//response:伺服器發出的數據

let server=http.createServer((request, response)=>{

//判斷接收到的url

switch(request.url){

case "/hello":

response.write("hi");

break;

case "/word":

response.write("gun");

break;

case "/bb.html":

response.write ("<html><head></head><body>Talk is cheap,show me the code</body></html>");

break;

}

//關閉

response.end();

});

//伺服器監聽的埠,填寫埠地址時,注意埠地址不能與其它應用程序衝突

server.listen(8000);

寫完代碼了,咋執行啊?

問的非常好!

這是今天的回家作業,自己想去。 鬧鬧狠狠的說到!

2分鐘看懂 Node.js 精髓

打開今日頭條,查看更多精彩圖片
喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

Linux運行級別和找回root密碼
xtrabackup部署以及使用

TAG:程序員小新人學習 |