天天看点

Node 中的Event模块详解

Events是Node最重要的模块,它提供了一个对象events.EventEmitter,EventEmitter 的核心是事件发射与事件监听器。

Node.js中大部分的模块,都继承自Event模块。

EventEmitter 支持若干个事件监听器,当事件发射时,注册到这个事件的事件监听器被依次调用,事件参数作为回调函数参数传递。

事件模块相关的方法主要有以下这些:

1. EventEmitter.on(event, listener)

注册监听事件。

参数1:event  事件名;

参数2:listener 回调函数;

// 调用events模块,获取events.EventEmitter对象
var EventEmitter = require('events').EventEmitter; 
// 实例化EventEmitter对象  
var ee = new EventEmitter();

// 注册监听事件someEvents
ee.on('someEvents', function(a, b) {
    console.log("触发了监听事件,参数为1为" + a + ",参数2为" + b );
});

// 第1次触发事件someEvents
ee.emit('someEvents', 'time', 'address');
// 触发了监听事件,参数为1为time,参数2为address

// 第2次触发事件someEvents
ee.emit('someEvents', 'name', 'age');
// 触发了监听事件,参数为1为name,参数2为age           

复制

2. EventEmitter.emit(event, [arg1], [arg2], [...]) 

触发指定的监听事件。

参数1:event  事件名;

参数2:[arg1] 可选参数,按顺序传入回调函数的参数;

返回值:该事件是否有监听;

// 调用events模块,获取events.EventEmitter对象
var EventEmitter = require('events').EventEmitter;
// 实例化EventEmitter对象  
var ee = new EventEmitter();

// 第1次注册监听事件someEvents
ee.on('someEvents', function (a, b) {
    console.log("触发了第1个监听事件,参数为1为" + a + ",参数2为" + b);
});

// 触发事件someEvents并返回布尔类型的结果值
var resultA = ee.emit('someEvents', 'time', 'address');
// 触发了第1个监听事件,参数为1为time,参数2为address

// 第2次注册监听事件someEvents
ee.on('someEvents', function (a, b) {
    console.log("触发了第2个监听事件,参数为1为" + a + ",参数2为" + b);
});

// 触发监听事件someEvents
ee.emit('someEvents', 'name', 'age');
// 触发了第1个监听事件,参数为1为time,参数2为address
// 触发了第2个监听事件,参数为1为time,参数2为address


// 尝试触发一个未注册的监听事件并返回布尔类型的结果值
var resultB = ee.emit('otherEvents', 'page', 'pagesize');

console.log(resultA);
// true
console.log(resultB);
// false           

复制

3. EventEmitter.once(event, listener)  

为事件注册一次性监听,触发一次后移除监听事件,后续再次触发将无效。

参数1:event  事件名;

参数2:listener 回调函数;

// 调用events模块,获取events.EventEmitter对象
var EventEmitter = require('events').EventEmitter;   
// 实例化EventEmitter对象 
var ee = new EventEmitter();


// 注册一次性监听事件someEvents
ee.once('someEvents', function(a, b) {
    console.log("触发了监听事件,参数为1为" + a + ",参数2为" + b);
});

// 触发一次性监听事件
ee.emit('someEvents', 'time', 'address');
// 触发了监听事件,参数为1为time,参数2为address

// 再次触发监听事件,并返回布尔结果值
var result =  ee.emit('someEvents', 'name', 'age');

console.log(result);
// false           

复制

4. EventEmitter.removeListener(event, listener)  

移除指定事件的监听器,注意:该监听器必须是注册过的。

参数1:event  事件名;

参数2:listener 回调函数;

// 调用events模块,获取events.EventEmitter对象
var EventEmitter = require('events').EventEmitter;   
// 实例化EventEmitter对象  
var ee = new EventEmitter();


// 监听事件1
var listener1 = function(a,b){
    console.log("触发了第1个监听事件,参数为1为" + a + ",参数2为" + b);
}

// 监听事件2
var listener2= function(a,b){
    console.log("触发了第2个监听事件,参数为1为" + a + ",参数2为" + b);
}

// 监听事件3
var listener3= function(a,b){
    console.log("触发了第3个监听事件,参数为1为" + a + ",参数2为" + b);
};

// 注册监听事件1
ee.on('someEvents', listener1);
// 注册监听事件2
ee.on('someEvents', listener2);
// 注册监听事件3
ee.on('someEvents', listener3);


// 移除监听事件1
ee.removeListener('someEvents', listener1);
// 移除监听事件2
ee.removeListener('someEvents', listener2);

// 触发监听事件
ee.emit('someEvents', 'time', 'address');
// 触发了第3个监听事件,参数为1为time,参数2为address           

复制

5. EventEmitter.removeAllListeners([event])   

移除(批定事件)所有监听器,一个事件可以有多个监听,需要全部移除时,可以用此方法。

参数1:event  事件名 可选参数。

需要特别注意的是,如果不传参数,将会移除所有的监听事件,比较暴力,建议慎用。

// 调用events模块,获取events.EventEmitter对象
var EventEmitter = require('events').EventEmitter; 
// 实例化EventEmitter对象    
var ee = new EventEmitter();

// 监听事件1
var listener1 = function(a,b){
    console.log("触发了第1个监听事件,参数为1为" + a + ",参数2为" + b);
};
// 监听事件2
var listener2= function(a,b){
    console.log("触发了第2个监听事件,参数为1为" + a + ",参数2为" + b);
};

// 注册监听事件1
ee.on('someEvents', listener1);
// 注册监听事件2
ee.on('someEvents', listener2);

// 注册监听另一个事件
ee.on('otherEvents',function(a,b){
    console.log("触发了另1个监听事件,参数为1为" + a + ",参数2为" + b);
});

// 移除所有的注册监听事件someEvents
ee.removeAllListeners('someEvents');

// 触发监听事件someEvents
ee.emit('someEvents', 'time', 'address');

// 触发另一个监听事件otherEvents
ee.emit('otherEvents', 'name', 'age');
// 触发了另1个监听事件,参数为1为name,参数2为age           

复制

6. EventEmitter.listeners(event)   

返回指定事件的注册监听的集合。

参数1:event 事件名 。

// 调用events模块,获取events.EventEmitter对象
var EventEmitter = require('events').EventEmitter;
// 实例化EventEmitter对象    
var ee = new EventEmitter();


// 监听事件1
var listener1 = function (a, b) {
    console.log("触发了第1个监听事件,参数为1为" + a + ",参数2为" + b);
};
// 监听事件2
var listener2 = function (a, b) {
    console.log("触发了第2个监听事件,参数为1为" + a + ",参数2为" + b);
};


// 注册监听事件1
ee.on('someEvents', listener1);
// 注册监听事件2
ee.on('someEvents', listener2);



// 注册监听另一个事件
ee.on('otherEvents', function (a, b) {
    console.log("触发了另1个监听事件,参数为1为" + a + ",参数2为" + b);
});

// 获取指定事件的监听数组
var listenerEventsArr = ee.listeners('someEvents');


for (var i = 0; i < listenerEventsArr.length; i++) {
    // 打印输出监听事件
    console.log(listenerEventsArr[i]);

    // [Function: listener1]
    // [Function: listener2]

};           

复制

7. EventEmitter.setMaxListeners (n)  

给EventEmitter设置最大监听数。

参数1: n  数字最大监听数。

正常情况下,可以设置的最大监听数为10个,如果超过了10个,就会出现警告,以下代码可以验证。

// 调用events模块,获取events.EventEmitter对象
var EventEmitter = require('events').EventEmitter;
// 实例化EventEmitter对象    
var ee = new EventEmitter();

//  给EventEmitter 添加11个监听
for (var i = 0; i <= 10; i++) {
    ee.on('someEvents',function(){
        console.log('第'+ (i +1) +'个监听');
    });
};           

复制

执行结果出现了如下的警告:

Warning: Possible EventEmitter memory leak detected. 11 someEvents listeners added. Use emitter.setMaxListeners() to increase limit。

系统认为侦听器太多,可能导致内存泄漏,所以存在这样一个警告,并且给出了提示,让我们用 emitter.setMaxListeners()  去提升限制。

// 调用events模块,获取events.EventEmitter对象
var EventEmitter = require('events').EventEmitter;
// 实例化EventEmitter对象    
var ee = new EventEmitter();

// 设置最大监听数为16个
ee.setMaxListeners(16);

//  给EventEmitter 添加11个监听
for (var i = 0; i <= 10; i++) {
    ee.on('someEvents',function(){
        console.log('第'+ (i +1) +'个监听');
    });
};

var listenerEventsArr = ee.listeners('someEvents');

// 打印输出监听事件数量
console.log(listenerEventsArr.length);
// 11           

复制

不知道为什么,11个事件是添加成功了,但是回调里没有打印输出,欢迎大家在评论区讨论!

8. EventEmitter.defaultMaxListeners (n)  

给所有EventEmitter设置最大监听,功能与setMaxListeners类似,不过setMaxListeners优先级要大于defaultMaxListeners,用的比较少,就不细说了。

9. EventEmitter.listenerCount(emitter, event)

返回指定事件的监听数,用的比较少,就不细说了。