Node.js課程紀要 - 第一節(jié)課

Node.js 是什么

簡單的說 Node.js 就是運行于服務(wù)端的JavaScript解釋器,既然是解釋器糕伐,有很多地方也把Node.js 叫成運行環(huán)境雕崩。為什么強調(diào)服務(wù)端呢?其實是相對于瀏覽器客戶端來說的军俊,之前的javaScript就是負責(zé)瀏覽器客戶端程序的開發(fā),而Node.js打破了這個禁制捧存,使用javaScript可以快速構(gòu)建網(wǎng)絡(luò)服務(wù)及應(yīng)用粪躬,如向客戶端提供接口担败。這對于熟悉和重點使用javaScript的程序員和公司來說是意義重大的,搭建一些服務(wù)的成本是能夠降低的镰官。比如因此出現(xiàn)的成為“全棧工程師”的一條新路提前,就不在這里討論了。

解釋器的一些知識可以參考:java的編譯器和解釋器淺析

Chrome V8 引擎

如果大家去查Node.js的資料泳唠,經(jīng)常會出現(xiàn)這個詞:V8引擎狈网。原話基本上都是這樣的 —— “Node.js 是一個基于 Chrome V8引擎的JavaScript運行環(huán)境”啃龋” 那什么是V8引擎呢拓哺?
Chrome V8引擎是一個JavaScript VM,在運行JavaScript之前脖母,相比其它的JavaScript的引擎轉(zhuǎn)換成字節(jié)碼或解釋執(zhí)行士鸥,V8采用即時編譯技術(shù)(JIT),直接將JavaScript代碼編譯成本地平臺的機器碼谆级,然后直接交由硬件執(zhí)行烤礁,并且使用了如內(nèi)聯(lián)緩存(inline caching)等方法來提高性能。
有了這些功能肥照,JavaScript程序在V8引擎下的運行速度媲美二進制程序脚仔。

Node.js 和Chrome V8 引擎的關(guān)系

從解釋器這個角度講,我認為Node.js == V8引擎舆绎;但整體的看鲤脏,實際上它是對V8進行了封裝及優(yōu)化。Node對一些特殊用例進行了優(yōu)化吕朵,提供了替代的API凑兰,使得V8在非瀏覽器環(huán)境下運行得更好。例如边锁,在服務(wù)器環(huán)境中姑食,處理二進制數(shù)據(jù)通常是必不可少的,但Javascript對此支持不足茅坛,因此音半,Node增加了Buffer類,方便并且高效地 處理二進制數(shù)據(jù)贡蓖。因此曹鸠,Node不僅僅簡單的使用了V8,還對其進行了優(yōu)化斥铺,使其在各環(huán)境下更加給力彻桃。

Node.js架構(gòu)

Node.js 使用了一個事件驅(qū)動、非阻塞式I/O的模型晾蜘。在這里我要強調(diào)邻眷,語言和框架固然重要眠屎,然是其中的設(shè)計思想才是我們要重點記住的,因為互通的就是這些思想肆饶,并不是代碼本身改衩。

node架構(gòu)

Node.js 標(biāo)準(zhǔn)庫,這部分是由 Javascript編寫的驯镊,即我們使用過程中直接能調(diào)用的 API葫督。
Node bindings,這一層是 Javascript與底層 C/C++ 能夠溝通的關(guān)鍵板惑,前者通過 bindings 調(diào)用后者橄镜,相互交換數(shù)據(jù)。
最下面這一層是支撐 Node.js 運行的關(guān)鍵冯乘,由 C/C++ 實現(xiàn)洽胶。
  • V8: Google 推出的 Javascript VM,也是 Node.js 為什么使用的是 Javascript的關(guān)鍵往湿,它為 Javascript提供了在非瀏覽器端運行的環(huán)境妖异,它的高效是 Node.js 之所以高效的原因之一惋戏。
  • Libuv: 它為 Node.js 提供了跨平臺领追,線程池,事件池响逢,異步 I/O 等能力绒窑,是 Node.js 如此強大的關(guān)鍵。
  • C-ares: 提供了異步處理 DNS 相關(guān)的能力舔亭。
  • http_parser些膨、OpenSSL、zlib 等: 提供包括 http 解析钦铺、SSL订雾、數(shù)據(jù)壓縮等其他的能力。
框架關(guān)系矛洞,作者@BusyRich

想要深入了解Node.js洼哎,幾個詞要記住并了解

  • RESTful API
  • 單線程
    Node.js 并沒有給 Javascript 執(zhí)行時創(chuàng)建新線程的能力,它的執(zhí)行線程是單線程的沼本。但這并不會影響它對任務(wù)進行并發(fā)處理噩峦,通過非阻塞操作和事件驅(qū)動就可以實現(xiàn)并發(fā)。
  • 非阻塞IO & 事件驅(qū)動


    事件驅(qū)動
  1. 每個Node.js進程只有一個主線程在執(zhí)行程序代碼抽兆,形成一個執(zhí)行棧(execution context stack)识补。
  2. 主線程之外,還維護了一個"事件隊列"(Event queue)辫红。當(dāng)用戶的網(wǎng)絡(luò)請求或者其它的異步操作到來時凭涂,node都會把它放到Event Queue之中祝辣,此時并不會立即執(zhí)行它,代碼也不會被阻塞导盅,繼續(xù)往下走较幌,直到主線程代碼執(zhí)行完畢。
  3. 主線程代碼執(zhí)行完畢完成后白翻,然后通過Event Loop乍炉,也就是事件循環(huán)機制,開始到Event Queue的開頭取出第一個事件滤馍,從線程池中分配一個線程去執(zhí)行這個事件岛琼,接下來繼續(xù)取出第二個事件,再從線程池中分配一個線程去執(zhí)行巢株,然后第三個槐瑞,第四個。主線程不斷的檢查事件隊列中是否有未執(zhí)行的事件阁苞,直到事件隊列中所有事件都執(zhí)行完了困檩,此后每當(dāng)有新的事件加入到事件隊列中,都會通知主線程按順序取出交EventLoop處理那槽。當(dāng)有事件執(zhí)行完畢后悼沿,會通知主線程,主線程執(zhí)行回調(diào)骚灸,線程歸還給線程池糟趾。
  4. 主線程不斷重復(fù)上面的第三步。

總結(jié):
我們所看到的node.js單線程只是一個js主線程甚牲,本質(zhì)上的異步操作還是由線程池完成的义郑,node將所有的阻塞操作都交給了內(nèi)部的線程池去實現(xiàn),本身只負責(zé)不斷的往返調(diào)度丈钙,并沒有進行真正的I/O操作非驮,從而實現(xiàn)異步非阻塞I/O,這便是node單線程和事件驅(qū)動的精髓之處了雏赦。

一個服務(wù)的搭建實例

將以下代碼存儲為js文件并運行劫笙,在瀏覽器中打開 http://127.0.0.1:8888/ ,你的第一個node應(yīng)用就能使用了喉誊。

var http = require('http');
http.createServer(function (request, response) {
    // 發(fā)送 HTTP 頭部 
    // HTTP 狀態(tài)值: 200 : OK
    // 內(nèi)容類型: text/plain
    response.writeHead(200, {'Content-Type': 'text/plain'});
    // 發(fā)送響應(yīng)數(shù)據(jù) "Hello World"
    response.end('Hello World\n');
}).listen(8888);
// 終端打印如下信息
console.log('Server running at http://127.0.0.1:8888/');

最后我們看2個有意思的程序邀摆,大家結(jié)合學(xué)到的知識,猜猜打印的結(jié)果可能是什么樣子的

第一個:

for (var i = 0; i <= 5; i++) {
     setTimeout(function() {
         console.log( i );
     }, i*1000);
     console.log( ' i : ' , i );
 }
 console.log( ' i i: ' , i );

第二個:

// 獲取當(dāng)前時間戳
var start = Date.now();
// 2秒后獲取時間間隔
setTimeout(function () {
  console.log(Date.now() - start);
}, 2000);
// 1秒后獲取時間間隔并開始運行長循環(huán)
setTimeout(function () {
  console.log(Date.now() - start);
  for (var i = 0; i < 1000000000; i++) {
    // 執(zhí)行長循環(huán)
  }
}, 1000);
//
var fs = require("fs");
fs.readFile('input.txt', function (err, data) {
  if (err) return console.error(err);
  console.log(data.toString());
});
console.log("程序執(zhí)行結(jié)束!");

感謝以下借鑒的大牛文章

https://www.runoob.com/nodejs/nodejs-http-server.html
https://blog.csdn.net/xiahuale/article/details/87005901
https://baike.baidu.com/item/node.js/7567977?fromtitle=nodejs&fromid=11244313&fr=aladdin

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末伍茄,一起剝皮案震驚了整個濱河市栋盹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌敷矫,老刑警劉巖例获,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件汉额,死亡現(xiàn)場離奇詭異,居然都是意外死亡榨汤,警方通過查閱死者的電腦和手機蠕搜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來收壕,“玉大人妓灌,你說我怎么就攤上這事∶巯埽” “怎么了虫埂?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長圃验。 經(jīng)常有香客問我掉伏,道長,這世上最難降的妖魔是什么澳窑? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任斧散,我火速辦了婚禮,結(jié)果婚禮上摊聋,老公的妹妹穿的比我還像新娘鸡捐。我一直安慰自己,他們只是感情好栗精,可當(dāng)我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布闯参。 她就那樣靜靜地躺著瞻鹏,像睡著了一般悲立。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上新博,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天薪夕,我揣著相機與錄音,去河邊找鬼赫悄。 笑死原献,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的埂淮。 我是一名探鬼主播姑隅,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼倔撞!你這毒婦竟也來了讲仰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤痪蝇,失蹤者是張志新(化名)和其女友劉穎鄙陡,沒想到半個月后冕房,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡趁矾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年耙册,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片毫捣。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡详拙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蔓同,到底是詐尸還是另有隱情溪厘,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布牌柄,位于F島的核電站畸悬,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏珊佣。R本人自食惡果不足惜蹋宦,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望咒锻。 院中可真熱鬧冷冗,春花似錦、人聲如沸惑艇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽滨巴。三九已至思灌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間恭取,已是汗流浹背泰偿。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蜈垮,地道東北人耗跛。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像攒发,于是被迫代替她去往敵國和親调塌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 一文淺析 Node.js 單線程高并發(fā)原理 Node 并非是真正意義上的單線程惠猿,它是主線程 "單線程"羔砾,通過事件驅(qū)...
    聰明的奇瑞閱讀 2,407評論 0 1
  • 前言 作為一名剛接觸前端的小白,想要通過文字記錄下自己在前端道路上學(xué)習(xí)到的知識。一方面幫助自己能夠更好地理解并梳理...
    迦葉凡閱讀 74,203評論 5 16
  • 個人入門學(xué)習(xí)用筆記蜒茄、不過多作為參考依據(jù)唉擂。如有錯誤歡迎斧正 目錄 簡書好像不支持錨點、復(fù)制搜索(反正也是寫給我自己看...
    kirito_song閱讀 2,472評論 1 37
  • JS的單線程異步是什么意思? 單線程異步其實屿聋,我第一次接觸到這個概念空扎,是很迷惑的,所以這里就將我自解惑之后的理解說...
    Tenloy閱讀 757評論 0 3
  • Node.js Node.js 就是運行在服務(wù)端的 JavaScript润讥。 Node.js 是一個基于Chrome...
    Gukson666閱讀 696評論 0 1