node.js之 EventEmitter

node的事件模块只包含了一个类:EventEmitter。这个类在node的内置模块和第三方模块中大量使用。EventEmitter本质上是一个观察者模式的实现。

所谓观察者模式:

它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知。

因此最基本的EventEmitter功能,包含了一个观察者和一个被监听的对象,对应的实现就是EventEmitter中的on和emit:

var events=require('events');
var eventEmitter=new events.EventEmitter();
eventEmitter.on('say',function(name){
    console.log('Hello',name);
})
eventEmitter.emit('say','Jony yu');

eventEmitter是EventEmitter模块的一个实例,通过eventEmitter的on方法监听,eventEmitter的emit方法say事件,发出say事件,从而执行相应的函数。

 

EventEmitter模块的基本用法

.addListener()或.on()为指定事件添加一个监听器到监听器数组尾部(这俩作用一样,on是addListener的简写形式)

prependListener(event,listener) 添加一个监听器到监听器数组头部

once(event, listener)                  添加一个单次监听器到监听器数组尾部, 监听器最多只会触发一次,触发后立刻解除该监听器。

removeListener 或 off                移除指定事件的某个监听器               

removeAllListeners([event])       移除所有事件的所有监听器, 如果指定事件,则移除指定事件的所有监听器。

setMaxListeners(n)                    默认情况下, EventEmitters 如果你添加的监听器超过 10 个就会输出警告信息。                                                                            setMaxListeners 函数用于提高监听器的默认限制的数量

listeners(event)                         返回指定事件的监听器数组

emit(event, [arg1], [arg2], [...])  按参数的顺序执行每个监听器,如果事件有注册监听返回 true,否则返回 false。

 

例子:

添加监听事件

var events = require('events'); 
var emitter = new events.EventEmitter(); 
emitter.on('someEvent', function(arg1, arg2) { 
	console.log('listener1', arg1, arg2); //执行多次
}); 
emitter.on('someEvent', function(arg1, arg2) { 
	console.log('listener2', arg1, arg2); //执行多次
}); 
emitter.once('someEvent', function(arg1, arg2) { 
	console.log('listener3', arg1, arg2); //只执行一次
}); 
emitter.prependListener('someEvent', function(arg1, arg2) { 
	console.log('listener4', arg1, arg2); //监听数组头部
}); 
emitter.emit('someEvent', 'arg1 参数', 'arg2 参数');
emitter.emit('someEvent', 'arg1 参数', 'arg2 参数');

移除事件

//event.js 文件
var events = require('events');
var eventEmitter = new events.EventEmitter();

// 监听器 #1
var listener1 = function listener1() {
   console.log('监听器 listener1 执行。');
}

// 绑定 connection 事件,处理函数为 listener1 
eventEmitter.addListener('connection', listener1);

// 处理 connection 事件 
eventEmitter.emit('connection');

// 移除监绑定的 listener1 函数
eventEmitter.removeListener('connection', listener1);
console.log("listener1 不再受监听。");

// 触发连接事件
eventEmitter.emit('connection');


console.log("程序执行完毕。");

移除所有监听事件:

// 监听器 #1
var listener1 = function listener1() {
   console.log('监听器 listener1 执行。');
}
var listener2 = function listener2() {
    console.log('监听器 listener2 执行。');
 }

eventEmitter.addListener('connection', listener1);

eventEmitter.on('connection2', listener2);
console.log(eventEmitter.listeners('connection') )
eventEmitter.removeAllListeners('connection') 
eventEmitter.emit('connection');
eventEmitter.emit('connection2');
eventEmitter.removeAllListeners() 
eventEmitter.emit('connection2');
console.log("程序执行完毕。");

设置监听器最大个数:

//event.js 文件
var events = require('events');
var eventEmitter = new events.EventEmitter();

// 监听器 #1
var listener1 = function listener1() {
   console.log('监听器 listener1 执行。');
}
var listener2 = function listener2() {
    console.log('监听器 listener2 执行。');
 }
 eventEmitter.setMaxListeners(3) 
eventEmitter.addListener('connection', listener1);
eventEmitter.addListener('connection', listener1);
eventEmitter.addListener('connection', listener1);
eventEmitter.addListener('connection', listener2);
eventEmitter.addListener('connection', listener1);
eventEmitter.addListener('connection', listener1);
eventEmitter.addListener('connection', listener1);
eventEmitter.addListener('connection', listener2);

  
eventEmitter.emit('connection');


console.log("程序执行完毕。");

 

error 事件

EventEmitter 定义了一个特殊的事件 error,它包含了错误的语义,我们在遇到 异常的时候通常会触发 error 事件。

当 error 被触发时,EventEmitter 规定如果没有响 应的监听器,Node.js 会把它当作异常,退出程序并输出错误信息。

我们一般要为会触发 error 事件的对象设置监听器,避免遇到错误后整个程序崩溃。例如:

var events = require('events'); 
var emitter = new events.EventEmitter(); 
emitter.emit('error');

运行时会显示以下错误:

node.js:201 
throw e; // process.nextTick error, or 'error' event on first tick 
^ 
Error: Uncaught, unspecified 'error' event. 
at EventEmitter.emit (events.js:50:15) 
at Object.<anonymous> (/home/byvoid/error.js:5:9) 
at Module._compile (module.js:441:26) 
at Object..js (module.js:459:10) 
at Module.load (module.js:348:31) 
at Function._load (module.js:308:12) 
at Array.0 (module.js:479:10) 
at EventEmitter._tickCallback (node.js:192:40)

继承 EventEmitter

大多数时候我们不会直接使用 EventEmitter,而是在对象中继承它。包括 fs、net、 http 在内的,只要是支持事件响应的核心模块都是 EventEmitter 的子类。

为什么要这样做呢?原因有两点:

首先,具有某个实体功能的对象实现事件符合语义, 事件的监听和发射应该是一个对象的方法。

其次 JavaScript 的对象机制是基于原型的,支持 部分多重继承,继承 EventEmitter 不会打乱对象原有的继承关系。

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值