一.事件监听,发布,移除
1.以下demo使用emitter.on和emitter.emit实现了事件的监听与发发布
let EventEmitter = require('events');
let emitter = new EventEmitter();
emitter.on('event1',function(param){
console.log('this is function1:'+param);
});
emitter.on('event1',function(param){
console.log('this is function2:'+param);
});
emitter.emit('event1','text');
2.默认情况下,事件监听器会按照添加的顺序进行执行, 既第一个事件处理函数没有完成,便不会触发下一个事件,如下:
let EventEmitter = require('events');
let emitter = new EventEmitter();
emitter.on('event1',function(){ // 订阅
console.time('1');
for (var i=0;i<1000000;i++){}
console.timeEnd('1');
});
emitter.on('event1',function(){ // 订阅
console.log('this is function2');
});
emitter.emit('event1'); // 发布
3.如果需要添加一个监听函数在数组的开头,可以使用prependListener,如下所示:
let EventEmitter = require('events');
let emitter = new EventEmitter();
emitter.on('event1',fn1);
emitter.prependListener('event1',fn2);
function fn1(param){
console.log('this is function1:'+param);
}
function fn2(param){
console.log('this is function2:'+param);
}
emitter.emit('event1','text');
// 打印结果如下:虽然function2的监听函数后于function1,但是却比function1先执行
this is function2:text
this is function1:text
4.为事件添加单次执行的函数,可以使用once,这里的事件监听器也是会按照添加的顺序进行执行 ,同样的也有对应prependOnceListener,可以将事件单次的添加到数组的开头(这里不做demo),实例如下:
let EventEmitter = require('events');
let emitter = new EventEmitter();
emitter.once('event1',fn1);
function fn1(param){
console.log('this is function1:'+param);
}
emitter.emit('event1','text');
emitter.emit('event1','text');
// 执行结果如下:
this is function1:text
5.如果需要删除某个事件的监听器,可以使用removeListener或者removeAllListeners,前者用于移除某一个监听器,后者用于移除所有的监听器
let EventEmitter = require('events');
let emitter = new EventEmitter();
emitter.on('event1',fn1);
emitter.on('event1',fn2);
function fn1(param){
console.log('this is function1:'+param);
}
function fn2(param){
console.log('this is function2:'+param);
}
emitter.emit('event1','text');
emitter.removeListener('event1',fn1);
emitter.emit('event1','text');
emitter.removeAllListeners('event1');
emitter.emit('event1','text');
// 打印如下:
this is function1:text
this is function2:text
this is function2:text
二.事件监听数量defaultMaxListeners
- 每个事件默认可以注册最多10个监听器,通过EventEmitter.defaultMaxListeners可以进行查看,如果需要改变,可以使用EventEmitter.defaultMaxListeners这个属性进行改变
- 如果需要对某一个EventEmitter实例进行更改,可以使用emitter.setMaxListeners(1)进行设置
- 注:对 EventEmitter.defaultMaxListeners 这个属性进行改变时,要慎重,因为它会影响所有的EventEmitter实例
- 注:我们在进行监听器添加时,添加的监听器最好不要超过设置的最大值,否则会发生内存泄漏
let EventEmitter = require('events');
console.log(EventEmitter.defaultMaxListeners); // 10
EventEmitter.defaultMaxListeners = 5;
console.log(EventEmitter.defaultMaxListeners); // 5
let emitter = new EventEmitter();
emitter.setMaxListeners(1);
console.log(emitter.getMaxListeners()); // 1
// 我们这里对emitter设置了最大的监听数为1,当监听器查出最大监听数,会报如下错误:
// (node:8408) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 2 event1 listeners added. Use emitter.setMaxListeners() to increase limit
emitter.on('event1',fn1);
emitter.on('event1',fn2);
function fn1(){
console.log('fn1');
}
function fn2(){
console.log('fn2');
}
三.eventNames和listenerCount
- eventName:根据触发器获取其监听的事件数组
- listenerCount:根据事件获取该事件的监听器的数量
let EventEmitter = require('events');
let emitter = new EventEmitter();
emitter.on('event1',fn1);
emitter.on('event1',fn2);
emitter.on('event2',fn2);
function fn1(param){
console.log('this is function1:'+param);
}
function fn2(param){
console.log('this is function2:'+param);
}
console.log(emitter.eventNames());
console.log(emitter.listenerCount('event1'));
// 打印如下:
[ 'event1', 'event2' ] // 获取emitter触发器监听的事件的数组
2 // 获取正在监听event1的事件的监听器的数量死
四.手写简单的on,once,emite,removeListener
class eventEmitter{
constructor(){
this._event = [];
}
on(eventName,callback){
if (!this._event[eventName]) {
this._event[eventName] = [callback];
}else{
this._event[eventName].push(callback);
}
}
emit(eventName,...args){
this._event[eventName].forEach((cb)=>{cb(...args)});
}
removeListener(eventName,callback){
if(this._event[eventName]){
this._event[eventName] = this._event[eventName].filter((cb)=>{return cb!=callback});
}
}
once(eventName,callback){
let fn = (...args)=>{
callback(...args);
this.removeListener(eventName,fn);
};
this.on(eventName,fn);
}
}
let emitter = new eventEmitter();
emitter.on('event1',fn1);
emitter.on('event1',fn2);
emitter.once('event2',fn1);
function fn1(param){
console.log('this is function1:'+param);
}
function fn2(param){
console.log('this is function2:'+param);
}
emitter.emit('event1','text');
emitter.removeListener('event1',fn1);
emitter.emit('event1','text');
emitter.emit('event2','text');
emitter.emit('event2','text');
参考文档: