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有问题欢迎与我讨论,共同进步。
// 移除绑定的全部监听器