Nodejs中不存在瀏覽器中冒泡,捕獲這些行爲,Nodejs中實現了events這個模塊,Nodejs中大多數模塊都集成了這個模塊,因此events是Nodejs中最重要的一個模塊。html
events只對外暴露一個對象,就是EventEmitter,EventEmitter做用只有2個,分別是:事件的發射和事件的監聽。瀏覽器
Node.js中,不少對象會發出事件。如,fs.readStream打開文件時會發出一個事件。 函數
全部發出事件的對象都是events.EventEmitter的實例,能夠經過require("event");得到event模塊。學習
監聽器函數(listeners)能夠添加給對象,對象發出事件時,對應的函數就會被執行。在監聽器函數中,this引用的是它(監聽器函數)ui
經過require('events').EventEmitter獲得EventEmitter類。this
當EventEmitter對象遇到錯誤時,一般會觸發error事件。error事件在Nodejs中是一種特殊狀況,若是沒有監聽器,那麼默認會打印出棧跟蹤器並退出程序。spa
爲事件綁定事件處理程序,能夠用emitter.addListener(event,listener)和emitter.on(event,listener),它們做用徹底同樣。傳入參數是事件(event)和處理函數(listener)。code
demo:test1.js內容以下server
var http = require('http'); var server = http.createServer(); // 爲request事件綁定處理函數 // 也可使用server.addListener server.on('request', function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('shiyanlou'); console.log('shiyanlou'); res.end(); }); server.listen(1337, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1337/');
使用 emitter.once(event,listener)綁定的事件監聽器只執行一次,而後就會被刪除掉。htm
demo:test2.js內容以下
var http = require('http'); var server = http.createServer(); // 爲request事件綁定處理函數,事件只會執行一次 server.once('request', function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('shiyanlou'); console.log('shiyanlou'); res.end(); }); server.listen(1337, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1337/');
移除監聽器使用emitter.removeListener(event,listener);
demo:test3.js內容以下
var http = require('http'); var server = http.createServer(); function callback(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('Hello World'); console.log('Hello World'); res.end(); } server.on('request', callback); // 移除綁定的監聽器callback server.removeListener('request', callback); server.on('request', function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('shiyanlou'); console.log('shiyanlou'); res.end(); }); server.listen(1337, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1337/');
運行結果只顯示shiyanliu,不顯示hello world,由於「hello world」的監聽器被移除了。
錯誤的移除事件不能移除匿名的事件處理程序,必須像上面同樣移除具名函數。
server.on('request', function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('shiyanlou'); console.log('shiyanlou'); res.end(); }); //錯誤的移除事件方法 server.removeListener('request',function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('shiyanlou'); console.log('shiyanlou'); res.end(); });
移除全部監聽器使用emitter.removeAllListener([event]) 。須要傳入某種類型的事件參數,不傳的話會把全部類型的事件監聽都移除掉。
demo:test4.js內容以下:
var http = require('http'); var server = http.createServer(); server.on('request', function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('shiyanlou,111'); console.log('shiyanlou,111'); res.end(); }); server.on('request', function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('shiyanlou,222'); console.log('shiyanlou,222'); res.end(); }); // 移除綁定的全部監聽器 server.removeAllListeners('request'); // 移除後再綁定一個有監聽器 server.on('request', function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('shiyanlou'); console.log('shiyanlou'); res.end(); }); server.listen(1337, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1337/');
瀏覽器只輸出shiyanlou
EventEmitter支持多個事件監聽器,最大值是10。便可用爲某個事件添加10個監聽函數,作10件事情。默認狀況下,超過10個就好警告提示,
這能幫咱們快速找到內存泄露的地方。
顯然,不是全部的事件觸發器都限制在10個監聽器,經過emitter.setMaxLisstener(n) 能夠設置同一事件的監聽器最大綁定數,若是設置爲0就是無限制。
使用emitter.emit(event,[arg1],[arg2],[...]) 能夠觸發自定義的事件。
demo:test5.js內容以下
var http = require('http'); var server = http.createServer(); // 綁定自定義事件myevent server.on('myevent', function(arg) { console.log(arg); }); // 觸發自定義事件 server.emit('myevent', 'shiyanlou'); server.listen(1337, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1337/');
運行結果在console界面輸出shiyanlou,說明觸發自定義事件成功。
使用EventEmitter.listenerCount(emitter,event) 能夠查看事件監聽器數量。
也能夠用emitter.listeners('event').length;來查看。
demo:test6.js內容以下
var http = require('http'); var events = require('events'); // 加載events模塊 var server = http.createServer(); server.on('request', function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('shiyanlou,111'); console.log('shiyanlou,111'); res.end(); }); server.on('request', function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('shiyanlou,222'); console.log('shiyanlou,222'); res.end(); }); server.listen(1337, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1337/'); //2種方法 查看server綁定的'request'事件的監聽器個數 var num = events.EventEmitter.listenerCount(server, 'request'); var num2=server.listeners('request').length; console.log(num); console.log(num2);
2種方法運行結果都輸出了2,由於server綁定了兩個監聽器到"request"事件。
Error:write after end【update20170327】
server.on('request', function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('shiyanlou,111'); console.log('shiyanlou,111'); res.end(); }); server.on('request', function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('shiyanlou,222'); console.log('shiyanlou,222'); res.end(); });
Once a writable stream is closed, it cannot accept anymore data。server綁定了2個request事件處理程序,第一個在res.write()後調用了res.end()結束了寫入流,因此再次調用res.write('shiyanlou,222');就會報錯,能夠註釋掉第一end()調用。
本文做者starof,因知識自己在變化,做者也在不斷學習成長,文章內容也不定時更新,爲避免誤導讀者,方便追根溯源,請諸位轉載註明出處:http://www.cnblogs.com/starof/p/5035522.html有問題歡迎與我討論,共同進步。
// 移除綁定的全部監聽器