阻塞i/o與非阻塞i/o
//阻塞i/o
var fs = require("fs");
var data = fs.readFileSync('input.txt');
console.log(data.toString());
console.log("程序執(zhí)行結(jié)束!");
//非阻塞i/o
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é)束!");
以上兩個(gè)實(shí)例我們了解了阻塞與非阻塞調(diào)用的不同。第一個(gè)實(shí)例在文件讀取完后才執(zhí)行完程序。 第二個(gè)實(shí)例我們不需要等待文件讀取完,這樣就可以在讀取文件時(shí)同時(shí)執(zhí)行接下來(lái)的代碼,大大提高了程序的性能。
因此,阻塞是按順序執(zhí)行的,而非阻塞是不需要按順序的,所以如果需要處理回調(diào)函數(shù)的參數(shù),我們就需要寫(xiě)在回調(diào)函數(shù)內(nèi)。
Node.js 事件循環(huán)
Node.js 是單進(jìn)程單線程應(yīng)用程序,但是通過(guò)事件和回調(diào)支持并發(fā),所以性能非常高。
Node.js 的每一個(gè) API 都是異步的,并作為一個(gè)獨(dú)立線程運(yùn)行,使用異步函數(shù)調(diào)用,并處理并發(fā)。
Node.js 基本上所有的事件機(jī)制都是用設(shè)計(jì)模式中觀察者模式實(shí)現(xiàn)。
Node.js 單線程類似進(jìn)入一個(gè)while(true)的事件循環(huán),直到?jīng)]有事件觀察者退出,每個(gè)異步事件都生成一個(gè)事件觀察者,如果有事件發(fā)生就調(diào)用該回調(diào)函數(shù).
Node.js 使用事件驅(qū)動(dòng)模型,當(dāng)web server接收到請(qǐng)求,就把它關(guān)閉然后進(jìn)行處理,然后去服務(wù)下一個(gè)web請(qǐng)求。
當(dāng)這個(gè)請(qǐng)求完成,它被放回處理隊(duì)列,當(dāng)?shù)竭_(dá)隊(duì)列開(kāi)頭,這個(gè)結(jié)果被返回給用戶。
這個(gè)模型非常高效可擴(kuò)展性非常強(qiáng),因?yàn)閣ebserver一直接受請(qǐng)求而不等待任何讀寫(xiě)操作。(這也被稱之為非阻塞式IO或者事件驅(qū)動(dòng)IO)
在事件驅(qū)動(dòng)模型中,會(huì)生成一個(gè)主循環(huán)來(lái)監(jiān)聽(tīng)事件,當(dāng)檢測(cè)到事件時(shí)觸發(fā)回調(diào)函數(shù)。
整個(gè)事件驅(qū)動(dòng)的流程就是這么實(shí)現(xiàn)的,非常簡(jiǎn)潔。有點(diǎn)類似于觀察者模式,事件相當(dāng)于一個(gè)主題(Subject),而所有注冊(cè)到這個(gè)事件上的處理函數(shù)相當(dāng)于觀察者(Observer)。
