眾所周知猬腰,nodeJs可以高性能的搭建網(wǎng)站,但是為什么nodeJs的性能特別高呢猜敢?
因?yàn)镹ode.js 是單進(jìn)程單線程應(yīng)用程序漆诽,但是通過事件和回調(diào)支持并發(fā),所以性能非常高锣枝。而且NodeJs的所有API都是異步的厢拭,并作為一個(gè)獨(dú)立線程運(yùn)行,使用異步函數(shù)調(diào)用撇叁,并處理并發(fā)供鸠。(nodeJs的事件采用的是設(shè)計(jì)模式中觀察者模式)
事件驅(qū)動(dòng)程序
為某個(gè)事件注冊(cè)了回調(diào),當(dāng)事件發(fā)生時(shí)執(zhí)行回調(diào)函數(shù)陨闹,這就是事件驅(qū)動(dòng)楞捂。這種回調(diào)的方式就可以不阻塞io,從而達(dá)到高性能的目的薄坏。
這個(gè)模型非常高效可擴(kuò)展性非常強(qiáng),因?yàn)閣ebserver一直接受請(qǐng)求而不等待任何讀寫操作寨闹。(這也被稱之為非阻塞式IO或者事件驅(qū)動(dòng)IO)
在事件驅(qū)動(dòng)模型中胶坠,會(huì)生成一個(gè)主循環(huán)來監(jiān)聽事件,當(dāng)檢測(cè)到事件時(shí)觸發(fā)回調(diào)函數(shù)繁堡。
EventEmitter
Node.js 所有的異步 I/O 操作在完成時(shí)都會(huì)發(fā)送一個(gè)事件到事件隊(duì)列沈善。
Node.js里面的許多對(duì)象都會(huì)分發(fā)事件:一個(gè)net.Server對(duì)象會(huì)在每次有新連接時(shí)分發(fā)一個(gè)事件, 一個(gè)fs.readStream對(duì)象會(huì)在文件被打開的時(shí)候發(fā)出一個(gè)事件椭蹄。 所有這些產(chǎn)生事件的對(duì)象都是 events.EventEmitter 的實(shí)例闻牡。
EventEmitter 的核心就是事件觸發(fā)與事件監(jiān)聽器功能的封裝。
EventEmitter默認(rèn)情況下最多可綁定十個(gè)事件绳矩。
下面一個(gè)event.js的示例:
var EventEmitter = require('events').EventEmitter;
var life = new EventEmitter();
life.setMaxListeners(11);
//addEventListener
function sleep(who){
console.log(who + ' is sleepping');
}
life.on('life', sleep);
life.on('life', function(who) {
console.log(who + ' is writing');
})
life.on('life', function(who) {
console.log(who + ' is working');
})
life.on('life', function(who) {
console.log(who + ' is coding');
})
life.on('life', function(who) {
console.log(who + ' is running');
})
life.on('life', function(who) {
console.log(who + ' is reading');
})
life.on('life', function(who) {
console.log(who + ' is playing');
})
life.on('life', function(who) {
console.log(who + ' is eatting');
})
life.on('life', function(who) {
console.log(who + ' is drinking');
})
life.on('life', function(who) {
console.log(who + ' is hunging');
})
life.on('anotherlife', function(who) {
console.log(who + ' is anotherlife one');
})
life.on('anotherlife', function(who) {
console.log(who + ' is anotherlife two');
})
//移除事件
life.removeListener('life',sleep);
//查看有多少事件
console.log(life.listeners().length);
console.log(EventEmitter.listenerCount(life,'life'));
//批量移除
life.removeAllListener('life');
//判斷事件是否被監(jiān)聽過
var hasLifeListener = life.emit('life','Jocelyn');
控制臺(tái)的輸出如下:
0
9