Node.js中多数对象都有事件分发,例如:
1.net Server对象每次有新连接时会分发一个事件
2. fs.readStream对象会在文件被打开时发出一个事件
上述示例中 net Server对象、fs.readStream对象都是events.EventEmitter的实例
EventEmitter 类:
events模块只提供了一个对象:events.EventEmitter.
EventEmitter的核心就是事件触发与事件监听功能的封装。
如何获取events模块? 如何创建EventEmitter对象?
```
// 引入 events 模块
var events = require('events');
// 创建 eventEmitter 对象
var eventEmitter = new events.EventEmitter();
```
EventEmitter用法示例:
```
// 引入 events 模块
var events = require('events');
// 创建 EventEmitter对象
var eventEmitter = new events.EventEmitter();
// 绑定 some_event 事件
eventEmitter.on("some_event",function(){
console.log('some_event事件成功触发');
});
setTimeout(function(){
// 触发 some_event事件
eventEmitter.emit('some_event');
},1000);
代码解释:
1秒后控制台输出some_event事件成功触发,
原理:event对象注册了事件some_event的一个监听器
然后我们通过 setTimeout 在 1000 毫秒以后向 event 对象
发送事件 some_event,此时会调用some_event 的监听器。
```
EventEmitter每一个事件由一个事件名和若干个参数组成,对于某一事件EventEmitter支持
若干个事件的监听,当事件触发时,注册到这个事件的监听器依次被调用,事件参数作为
回调函数参数传递
```
// 引入 events 模块
var event = require('events');
// 创建 EventEmitter对象
var eventEmitter = new event.EventEmitter();
// 绑定 some_event事件
eventEmitter.on("some_event",function(arg1,arg2,arg3){
console.log("some_event事件监听1",arg1,arg2,arg3);
});
// 绑定 some_event事件
eventEmitter.on('some_event',function(arg1,arg2,arg3){
console.log("some_event事件监听2",arg1,arg2,arg3);
});
// 触发 some_event事件
eventEmitter.emit('some_event',"参数1","参数2","参数3");
运行结果:
some_event事件监听1 参数1 参数2 参数3
some_event事件监听2 参数1 参数2 参数3
```
EventEmitter相关API介绍:
1. on(event, listener) 为指定事件注册一个监听器,接受一个字符串 event 和一个回调函数。
2. once(event, listener) 为指定事件注册一个单次监听器,即 监听器最多只会触发一次,触发后立刻解除该监听器。
3. emit(event, [arg1], [arg2], [...]) 按参数的顺序执行每个监听器,如果事件有注册监听返回 true,否则返回 false。
4. addListener(event, listener) 为指定事件添加一个监听器到监听器数组的尾部。
```
// 引入events模块
var events = require('events');
// 创建 EventEmitter 对象
var eventEmitter = new events.EventEmitter();
// 创建监听器 listener
var listener = function listener(){
console.log("监听器listener执行");
}
// 添加监听器 listener 到 some_event 事件上
eventEmitter.addListener("some_event",listener);
// 触发监听器
eventEmitter.emit('some_event');
```
-
listenerCount(emitter, event) 返回指定事件的监听器数量。
``` // 引入events模块 var events = require('events'); // 创建 EventEmitter 对象 var eventEmitter = new events.EventEmitter(); // 创建监听器 listener var listener = function listener(){ console.log("监听器listener执行"); } // 添加监听器 listener 到 some_event 事件上 eventEmitter.addListener("some_event",listener); // 为some_event事件添加监听器 var listenerNum = eventEmitter.listenerCount('some_event'); console.log("监听器的数量: "+listenerNum); 运行结果: 监听器的数量: 1 ```
6.removeListener(event, listener) 移除指定事件的某个监听器,监听器必须是该事件已经注册过的监听器。
```
// 引入events模块
var events = require('events');
// 创建 EventEmitter 对象
var eventEmitter = new events.EventEmitter();
// 创建监听器 listener
var listener = function listener(){
console.log("监听器listener执行");
}
// 添加监听器 listener 到 some_event 事件上
eventEmitter.addListener("some_event",listener);
// 获取 some_event 事件上监听器数量
var listenerNum = eventEmitter.listenerCount('some_event');
console.log("监听器删除前的数量: "+listenerNum);
// 删除 some_event 事件上 名为listener监听器的监听器
eventEmitter.removeListener('some_event',listener);
var listenerNum = eventEmitter.listenerCount('some_event');
console.log("监听器删除后的数量: "+listenerNum);
运行结果:
监听器删除前的数量: 1
监听器删除后的数量: 1
```
- removeAllListeners([event]) 移除所有事件的所有监听器, 如果指定事件,则移除指定事件的所有监听器。
// 引入events模块
var events = require('events');
// 创建 EventEmitter 对象
var eventEmitter = new events.EventEmitter();
// 创建监听器 listener_1
var listener_1 = function listener_1(){
console.log("监听器listener_1执行");
}
// 创建监听器 listener_2
var listener_2 = function listener_2(){
console.log("监听器listener_2执行");
}
// 添加监听器 listener_1 到 some_event 事件上
eventEmitter.addListener("some_event",listener_1);
// 添加监听器 listener_2 到 some_event 事件上
eventEmitter.addListener("some_event",listener_2);
// 获取 some_event 事件上监听器数量
var listenerNum = eventEmitter.listenerCount('some_event');
console.log("监听器删除前的数量: "+listenerNum);
// 删除 some_event 事件上 所有的监听器
eventEmitter.removeAllListeners('some_event'); //
var listenerNum = eventEmitter.listenerCount('some_event');
console.log("监听器删除后的数量: "+listenerNum);
运行结果:
监听器删除前的数量: 2
监听器删除后的数量: 0
- listeners(event) 返回指定事件的监听器数组。
// 引入events模块
var events = require('events');
// 创建 EventEmitter 对象
var eventEmitter = new events.EventEmitter();
// 创建监听器 listener_1
var listener_1 = function listener_1(){
console.log("监听器listener_1执行");
}
// 创建监听器 listener_2
var listener_2 = function listener_2(){
console.log("监听器listener_2执行");
}
// 添加监听器 listener_1 到 some_event 事件上
eventEmitter.addListener("some_event",listener_1);
// 添加监听器 listener_2 到 some_event 事件上
eventEmitter.addListener("some_event",listener_2);
// 获取 some_event事件上所有的监听器
var listeners = eventEmitter.listeners('some_event');
console.log("listeners: "+listeners);
运行结果:
listeners: function listener_1(){
console.log("监听器listener_1执行");
},function listener_2(){
console.log("监听器listener_2执行");
}
- setMaxListeners(n) 默认情况下, EventEmitters 如果你添加的监听器超过 10 个就会输出警告信息。 setMaxListeners 函数用于提高监听器的默认限制的数量。
Error事件
EventEmitter定义了一个特殊的事件error,其包含了错误的语义,遇到异常的时候会触发error事件。当error被触发时
EventEmitter规定如果没有响应监听器,Node.js会把它当做异常,退出程序并输出错误信息
因此,一般我们会为触发error事件的对象设置监听器,避免遇到错误后整个程序崩溃
var events = require('events');
var eventEmitter = new events.EventEmitter();
eventEmitter.emit('error');
运行结果:
events.js:165
throw err;
^
Error: Uncaught, unspecified "error" event. (undefined)
at EventEmitter.emit (events.js:163:17)
at Object.<anonymous> (E:\nodejs\2017-9-13 095510\eventEmitter.js:6:14)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:390:7)
at startup (bootstrap_node.js:150:9)
继承 EventEmitter
多数时候我们不户籍直接使用EventEmitter,而是在对象中继承它,其中包括 fs,net,http在内,只要支持事件响应
的核心模块都是EventEmitter的子类
原因有两点:哪两点呢?