亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

node.js的事件機(jī)制

 更新時(shí)間:2017年02月08日 14:11:21   作者:楊帥前端攻城獅  
本文主要介紹了node.js的事件機(jī)制,具有很好的參考價(jià)值,下面跟著小編一起來看下吧

首先, 補(bǔ)充下對(duì)node 的理解:

nodeJs 是一個(gè)單進(jìn)程單線程應(yīng)用程序, 但是通過事件和回調(diào)支持并發(fā), 所以性能非常高~

那么什么是單進(jìn)程單線程呢~(寫給語文跟我一樣不好的小伙伴)

我們來看下單進(jìn)程和多進(jìn)程的區(qū)別:

1.  多進(jìn)程的優(yōu)勢(shì)在于任務(wù)的獨(dú)立性,比如某個(gè)任務(wù)單獨(dú)作為一個(gè)進(jìn)程的話,崩潰只影響自己的服務(wù),其他任務(wù)不受影響.如果是多個(gè)任務(wù)在同一個(gè)進(jìn)程內(nèi)部利用多個(gè)線程進(jìn)行處理,某個(gè)線程發(fā)生了未處理的異常的話,會(huì)導(dǎo)致整個(gè)進(jìn)程完蛋,所有的任務(wù)跟著遭殃

2.  從資源分配上來說,多進(jìn)程方案比多線程方案更加靈活和自由

3. 不過任務(wù)間的通信方面多進(jìn)程要比多線程復(fù)雜些,編一個(gè)好的多進(jìn)程通信方案要比多線程間的通信方案困難多了(小伙伴們注意區(qū)分進(jìn)程和線程喲~)

以web server為例的話,比如我的服務(wù)器上架設(shè)了三個(gè)網(wǎng)站,如果是用一個(gè)進(jìn)程管理的話, 網(wǎng)站A遭受攻擊死掉了,意味著另外兩個(gè)網(wǎng)站會(huì)出現(xiàn)同樣的現(xiàn)象. 如果是分開獨(dú)立的進(jìn)程的話,三個(gè)網(wǎng)站互不影響

具體來分呢, 單進(jìn)程對(duì)比多進(jìn)程有什么優(yōu)點(diǎn)呢:

1)  初期實(shí)現(xiàn)起來比較簡(jiǎn)單快速, 而且不用考慮進(jìn)程間通信的工作量

2) 單一性使得部署和運(yùn)營(yíng)比較簡(jiǎn)單(這還用說  / 白眼ing)

3) 內(nèi)存占用少, 不過呢, 現(xiàn)在內(nèi)存很廉價(jià), 但是一分錢也是錢呀!

4) 進(jìn)程內(nèi)部通信效率比IPC/scoket(多進(jìn)程數(shù)據(jù)通訊的終端)等要高效,  我一嗓子你就聽見了, 就不用費(fèi)力氣裝個(gè)電話了

當(dāng)然, 肯定優(yōu)缺點(diǎn)!不然花那么多錢開多進(jìn)程的人也太蠢了 ~

單進(jìn)程對(duì)比多進(jìn)程的缺點(diǎn)~

1) 中后期隨著業(yè)務(wù)邏輯的復(fù)雜化和需求的增加,這個(gè)單進(jìn)程會(huì)變得臃腫, 難以維護(hù)。 一個(gè)任務(wù)分解成多個(gè)進(jìn)程會(huì)使單個(gè)進(jìn)程的邏輯簡(jiǎn)單,而不容易出錯(cuò)

2) 同進(jìn)程內(nèi)模塊間是強(qiáng)依賴關(guān)系,需要在一起編譯相互的影響也比較大。 這相對(duì)于多進(jìn)程間通信來說, 耦合度較大(不符合高內(nèi)聚低耦合的偉大思想), 不利于多團(tuán)隊(duì)并行開發(fā)。 多進(jìn)程更便于多語言的協(xié)作開發(fā)。

3)任何模塊的崩潰都將導(dǎo)致整個(gè)進(jìn)程的失效,多進(jìn)程模式更加穩(wěn)定健壯,業(yè)務(wù)處理程序隔離運(yùn)行, 一個(gè)go home不會(huì)影響其他(你敢崩我也崩);

4) 性能問題: 如果不支持進(jìn)程間數(shù)據(jù)通訊的話,單進(jìn)程的容量是受限的, 這個(gè)性能瓶頸對(duì)于支持群組類服務(wù)的尤其需要考慮。多進(jìn)程部署極其靈活,可以擴(kuò)充機(jī)器數(shù)量來提高系統(tǒng)處理性能,還可以從硬件上避免單點(diǎn)故障。(一個(gè)人承受不來)

5) 單進(jìn)程中多線程難調(diào)試( 一槍開出去, 一群人倒了, 我還得檢查一下誰中槍了才能給你debug)

舉個(gè)小栗子

你有一個(gè)對(duì)象, 對(duì)象特別挑食, 但是對(duì)象只喜歡一種菜, 你每天做給她吃。

這就是個(gè)單進(jìn)程單線程的模型,  如果你做的不好吃了, 對(duì)象不吃了。

但是我有一個(gè)對(duì)象, 她喜歡吃10種菜, 我每天端過去10份, 哪天其中某一份醋放多了, 對(duì)象說真難吃, 今天不吃了。這就是單進(jìn)程多線程的模型。一個(gè)菜不好吃導(dǎo)致對(duì)象不吃了(全部線程崩掉)

..  如果我有兩個(gè)對(duì)象..  每個(gè)對(duì)象喜歡吃一種菜

ok,  一個(gè)對(duì)象覺得好吃, 吃的臉圓圓的三下巴, 一個(gè)覺得不好吃常年不吃, 骨瘦如柴。

這就是多進(jìn)程單線程互不影響的模型.. 多進(jìn)程多線程我就不舉栗了 ~

說到這里, 小伙伴有沒有對(duì)單進(jìn)程單線程有一些理解呢。nodeJs 就是單進(jìn)程單線程的應(yīng)用程序, 進(jìn)程間互不影響, 綁定多個(gè)事件可以同時(shí)觸發(fā)~  不用等你完了我再有動(dòng)作, 所以nodeJs性能很高。

nodeJs 單線程類似進(jìn)入一個(gè)while(true ) 的事件循環(huán), 知道沒有事件觀察者的時(shí)候退出(每綁定一個(gè)事件, 就生成一個(gè)事件觀察者), 當(dāng)有事件發(fā)生的時(shí)候, 就會(huì)調(diào)用該事件的回調(diào)函數(shù)。

事件驅(qū)動(dòng)程序

nodeJs 使用事件驅(qū)動(dòng)模型(稍后說), 當(dāng)web server 接收到請(qǐng)求時(shí), 就把它關(guān)閉然后進(jìn)行處理, 然后去服務(wù)下一個(gè)web 請(qǐng)求??梢岳斫獬晌矣|發(fā)事件, 就先關(guān)閉這個(gè)事件驅(qū)動(dòng), 然后處理, 我覺得是在防止二次觸發(fā)~ 造成不正確的負(fù)載和意料之外的結(jié)果,這個(gè)模型非常高效可擴(kuò)展性非常強(qiáng),因?yàn)閣ebserver一直接受請(qǐng)求而不等待任何讀寫操作。(這也被稱之為非阻塞式IO或者事件驅(qū)動(dòng)IO)

可能有的小伙伴會(huì)問了, 什么是 事件驅(qū)動(dòng)模型呢~ 

其實(shí)在了解事件驅(qū)動(dòng)之前, 我們可以先看一下事件驅(qū)動(dòng)的三大要素:

1) 事件源:  誰來接受外部事件

2) 偵聽器:  能夠接收事件源通知的對(duì)象

3) 事件處理程序:  用于處理事件

好, 包含以上三點(diǎn)的就是一個(gè)完整的事件驅(qū)動(dòng)程序。

舉個(gè)栗子

如果有一天你走在路上一不小心被天上掉下來的花瓶砸到了,并且暈死了過去。那么整個(gè)過程其實(shí)就是一個(gè)事件處理流程,而且我們可以非常方便的分析出剛才所提到的事件驅(qū)動(dòng)模型中的三大要素。

1.被砸暈的這個(gè)人其實(shí)就是事件源,因?yàn)樗悄軌蚪邮艿酵獠康氖录脑大w。

2.偵聽器就是這個(gè)人的大腦神經(jīng),因?yàn)樗鼤?huì)感知到疼痛。

3.事件處理就是這個(gè)人暈死了過去。

在事件驅(qū)動(dòng)模型中,會(huì)生成一個(gè)主循環(huán)來監(jiān)聽事件,當(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)。

說了那么多, 事件綁定怎么寫呢。

在node 里, 有個(gè)事件模塊 events,  我們可以通過實(shí)例化的events 對(duì)象 來綁定事件。

上代碼:

var event = require('events'); // 引入事件模塊
var eventObj = new event(); // 實(shí)例化一個(gè)事件對(duì)象
eventObj.on('起床', function() { // 綁定事件和事件回調(diào)
console.log('洗臉?biāo)⒀?);

});
eventObj.emit('起床'); // 觸發(fā)事件的方法

結(jié)果是符合預(yù)期的。

但是有一點(diǎn)需要注意哦, 當(dāng)你想移除事件的時(shí)候, 直接eventObj.removeListener(‘起床')

然后各種報(bào)錯(cuò)~

其實(shí)正確的移除事件的方法是這樣的~

上代碼:

var event = require('events'); // 引入事件模塊
var eventObj = new event(); // 實(shí)例化一個(gè)事件對(duì)象
function getUp() {
console.log('洗臉?biāo)⒀?);
}
eventObj.on('起床', getUp);
eventObj.emit('起床');
eventObj.removeListener('起床', getUp);
eventObj.emit('起床');

成功移除事件~

node 還提供了只觸發(fā)單次事件的方法~

eventObj.once(‘起床', getUp)

還有移除全部事件呀~

eventObj.removeAllListeners(getUp), 像我這樣指定了getUp的事件, 則移除所有觸發(fā)該事件的監(jiān)聽器。

eventObj.setMaxListeners(n)  參數(shù)是一個(gè)數(shù)字, 因?yàn)閚ode默認(rèn)了綁定事件最多10個(gè), 10個(gè)以上的時(shí)候會(huì)警告。 如果不想被警告就設(shè)置最大監(jiān)聽器個(gè)數(shù)咯~

eventObj.listeners(even)  返回指定事件的監(jiān)聽器數(shù)組

eventObj.emit(getUp, [arg1], [arg2], [...])

按照參數(shù)的順序執(zhí)行事件,  返回值是true或者false。有此監(jiān)聽事件就返回true。

不知道小伙伴們有沒有疑惑,  我明明已經(jīng)把events 模塊加載過來了, 為什么還要實(shí)例化才能用呢~ 

大多數(shù)時(shí)候我們不會(huì)直接使用 EventEmitter,而是在對(duì)象中繼承它。包括 fs、net、 http 在內(nèi)的,只要是支持事件響應(yīng)的核心模塊都是 EventEmitter 的子類。

為什么要這樣做呢?原因有兩點(diǎn):

首先,具有某個(gè)實(shí)體功能的對(duì)象實(shí)現(xiàn)事件符合語義(可以自己命名了啊喂(#`O′) ), 事件的監(jiān)聽和發(fā)射都應(yīng)該是一個(gè)對(duì)象的方法。

其次 JavaScript 的對(duì)象機(jī)制是基于原型的, 支持部分多重繼承,繼承 EventEmitter不會(huì)打亂對(duì)象原有的繼承關(guān)系。

Node 應(yīng)用程序是如何工作的?

在 Node 應(yīng)用程序中,執(zhí)行異步操作的函數(shù)將回調(diào)函數(shù)作為最后一個(gè)參數(shù), 回調(diào)函數(shù)接收錯(cuò)誤對(duì)象作為第一個(gè)參數(shù)。

接下來讓我們來重新看下前面的實(shí)例,創(chuàng)建一個(gè) input.txt ,文件內(nèi)容如下:

123456123123

創(chuàng)建 main.js 文件,代碼如下:

var fs = require("fs");
fs.readFile('input.txt', function (err, data) {
 if (err){
 console.log(err.stack);
 return;
 }
 console.log(data.toString());});
console.log("程序執(zhí)行完畢");

以上程序中 fs.readFile() 是異步函數(shù)用于讀取文件。 如果在讀取文件過程中發(fā)生錯(cuò)誤,錯(cuò)誤 err 對(duì)象就會(huì)輸出錯(cuò)誤信息。

如果沒發(fā)生錯(cuò)誤,readFile 跳過 err 對(duì)象的輸出,文件內(nèi)容就通過回調(diào)函數(shù)輸出。

執(zhí)行以上代碼,執(zhí)行結(jié)果如下:

123456123123

接下來我們刪除 input.txt 文件,執(zhí)行結(jié)果如下所示:

程序執(zhí)行完畢Error: ENOENT, open 'input.txt'

因?yàn)槲募?input.txt 不存在,所以輸出了錯(cuò)誤信息。

以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持腳本之家!

相關(guān)文章

最新評(píng)論