說明:該學(xué)習(xí)筆記參考《深入淺出Node.js》在學(xué)習(xí)過程中钥屈,添加了自己的理解和適當(dāng)?shù)难a充悟民!僅供參考!
NodeJs的出現(xiàn)篷就,讓JavaScript工程師實現(xiàn)了獨自完成全棧的夢想射亏。NodeJs作為后端JavaScript的運行平臺,保留了前端瀏覽器中那些熟悉的接口竭业,沒有改寫語言本身的任何特性智润,依然基于作用鏈和原型鏈。
NodeJs有以下幾個特點:
異步I/O
異步I/O的最常見實現(xiàn)場景就是發(fā)起Ajax調(diào)用未辆。這里演示的是一個Ajax請求:
$.post("/url", {"title": "這是參數(shù)"}窟绷, function(data){
console.log("收到響應(yīng)");
});
console.log("發(fā)送Ajax結(jié)束");
這里,我們會注意到咐柜,輸出“發(fā)送Ajax結(jié)束”并不一定是在輸出“收到響應(yīng)”之后兼蜈,因為“收到響應(yīng)”的執(zhí)行時間是不被預(yù)期的。這里是比較重要的異步的原則:‘Don`t call me, I will call you’炕桨,注重結(jié)果饭尝,不關(guān)心過程肯腕。
在NodeJs中献宫,絕大多數(shù)的操作都是以異步的方式進行調(diào)用。在NodeJs中实撒,我們可以從語言層面很自然的進行并行I/O操作姊途,每個調(diào)用之間無需等待其他調(diào)用結(jié)束,在編程模型上可以極大的提升效率。
這里是兩個文件讀取任務(wù)的耗時取決于最慢的那個文件讀取的耗時:
var fs = require("fs");
fs.readFile("/path1", function(err, file){
console.log("讀取文件1完成");
});
fs.readFile("/path2", function(err, file){
console.log("讀取文件2完成");
});
事件與回調(diào)函數(shù)
NodeJs是將前端瀏覽器中廣泛且成熟的事件引入后端倒得,配合異步I/O固阁,將事件點暴露給業(yè)務(wù)邏輯。
var http = require("http");
var querystring = require("querystring");
// 偵聽服務(wù)其的request事件
http.createServer(function(req, res){
var postData = '';
req.setEncoding('utf8');
// 偵聽請求的data事件
req.on('data', function(chunk){
postData += chunk;
});
// 偵聽請求的end事件
req.on('end', function(){
res.end(postData);
});
}).listen(8080);
console.log('server start at port:8080')
在web服務(wù)器綁定request事件贡茅,對于請求對象秘蛇,為其綁定data事件和end事件。相應(yīng)的在前端Ajax請求中綁定success事件顶考,在發(fā)出請求后赁还,只需關(guān)心請求成功時執(zhí)行相應(yīng)的業(yè)務(wù)邏輯即可。
$.ajax({
'url': '127.0.0.1:8080',
'method': 'POST',
'data': {},
'success': function(data){
console.log(data);
}
})
以上代碼只是演示驹沿,此處的ajax并不能運行艘策。在此只是說明“事件”。
事件的編程方式具有輕量級渊季、松耦合朋蔫、只關(guān)注事務(wù)點等優(yōu)勢。但是也會造成在多個異步任務(wù)的場景下却汉,事件和事件之間各自獨立驯妄,如何協(xié)作是一個重要的問題。
回調(diào)函數(shù)無處不在病涨。在JavaScript中富玷,是將函數(shù)作為第一等公民來對待的,可以將函數(shù)作為對象傳遞給方法作為參數(shù)進行調(diào)用(這里說的是不是閉包既穆?可以去深揪一下赎懦!)
回調(diào)函數(shù)是最好的接受異步調(diào)用、返回數(shù)據(jù)的方式幻工,但是這種編程方式對于同步思路編程的人來說励两,是一大挑戰(zhàn)。代碼的編寫順序與執(zhí)行順序并無關(guān)系囊颅,在流程控制方面当悔,由于穿插了異步和回調(diào)使得變得不是那么一目了然。但是對于業(yè)務(wù)的劃分和對事件的提煉上復(fù)雜度與同步方式是一致的踢代。
單線程
NodeJs保持了JavaScript在瀏覽器中的單線程的特點盲憎。而且在NodeJs中,JavaScript與其他線程是無法共享任何狀態(tài)的胳挎。
單線程的最大好處就是:不用向多線程那樣處處在意狀態(tài)的同步問題饼疙,沒有死鎖的的存在,也沒有線程上下文交換(這點需要深入解釋下)所帶來的性能上的開銷慕爬。
當(dāng)然單線程也是有很大的弱點窑眯,但是必須要積極面對才能享受到node帶來的好處屏积。主要有以下三大方面:
- 無法利用多核CPU。
- 錯誤會引起整個應(yīng)用的退出磅甩,應(yīng)用的健壯性值得考驗炊林。
- 大量計算占用CPU導(dǎo)致無法繼續(xù)調(diào)用異步I/O。
在瀏覽器中JavaScript與UI共用一個線程卷要,JavaSript長時間執(zhí)行會導(dǎo)致UI的渲染和相應(yīng)被終端(這里思考瀏覽器加載資源的方式是并行還是串行渣聚,如何提高這方面的性能!)
第三個弱點僧叉,有相應(yīng)的解決方案饵逐,這里暫時先不提!
跨平臺
兼容于Windows和Linux平臺彪标。
應(yīng)用場景
I/O密集型
NodeJs擅長I/O密集型的應(yīng)用場景倍权,面向網(wǎng)絡(luò)且擅長并行I/O,能夠有效的組織更多的硬件資源捞烟,
I/O密集的優(yōu)勢主要在于NodeJs利用事件循環(huán)的處理能力薄声,而不是啟動每一個線程為每一個請求服務(wù),資源占用極少题画。
分布式應(yīng)用
與遺留系統(tǒng)和平相處
是否不擅長CPU密集型業(yè)務(wù)
這里簡單的認識NodeJs默辨,了解了其特性和應(yīng)用場景,接下來苍息,需要深入了缩幸,加油哦!