1. Events模块简介
-
node的特性:
单线程
异步
非阻塞I/O
基于事件驱动
的运行在服务器端轻量、高效的脚本语言; -
Events模块是nodejs的核心模块,是node实现事件驱动的基础,node中几乎所有的模块(如http, fs等)都继承该模块;
-
Events模块实现了事件注册,通知等功能,是
观察者模式(事件发布/订阅模式)
的实现; -
只要继承EventEmitter类,就可拥有事件注册、触发事件等,所有能触发事件的对象都是EventEmitter类的实例, 例如:
- net.Server 对象会在每次有新连接时触发事件;
- fs.ReadStream 会在文件被打开时触发事件;
- 流对象 会在数据可读时触发事件;
-
创建一个新类, 使支持 EventEmitter 事件
eg1: 借助util模块
let EventEmitter = require('events');
let util = require('util');
function WriteStream () {
EventEmitter.call(this); //继承私有属性
}
util.inherits(WriteStream, EventEmitter); //原型继承,继承公有
/**
* 定义一个WriteStream类,把EventEmitter类的方法添加到新创建的WriteStream 类中,使WriteStream的实例具有EventEmitter的方法。
* 相当于:
* Object.setPrototypeOf(ctor.prototype, superCtor.prototype); //指定的对象的原型
* ctor.prototype.__proto__ = superCtor.prototype;
*/
eg2: 借助es6 extends方法
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', () {
console.log('触发了一个事件了');
});
myEmitter.emit('event'); //触发事件
当我们订阅了'event'事件后,可以在任何地方通过emit('event')来执行事件回调;
复制代码
2. 相关API
1. 导入模块(创建emitter实例)
var EE = require('events'); //events模块只提供了一个EventEmitter类,所以返回的就是EventEmitter
2. 注册绑定事件
EE.addListener(event, listener);
EE.on(event, listener); //相当于增加观察者,addListener和on这两个方式作用是一样的
EE.once(event, listener); //绑定的事件监听器只会执行一次,然后就会被删除掉
//添加了任意的监听函数时会触发newListener
EE.on('newListener', (type, listener) => {
});
EE.on('removeListener');
3. 触发事件
EE.emit(event);
4. 移除事件
EE.removeListener(event, listener);
EE.removeAllListeners([event]); //移除所有
5. 其它api
EE.setMaxListeners(n); //设置同一事件的监听器最大绑定数,默认情况下,超过10个就会警告;设置为0,是无限制;
EE.listenerCount() //查看事件监听器数量
复制代码
3. 简单实现一个自己的myEventEmitter库
首先实现这个myEventEmitter库,需要先对观察者模式进行了解,这样写起来才会得心应手;
观察者模式管理消息分发的一种方式,这种模式中 ,发布消息的一方不需要知道这个消息会给谁,而订阅一方也无需知道消息的来源。
简单原理描述:this.events维护一个信号对应函数的列表,通过这个索引,可以对这个信号进行增、删等操作,你只需要按照这个信号执行对象的回调函数;
class MyEvents {
constructor () {
this.events = {} //存储事件监听函数
this.maxListeners = 10 //一种函数类型,最大监听函数数量
}
setMaxListeners (maxNum) {
this.maxListeners = maxNum
}
getMaxListeners () {
return this.maxListeners
}
listeners (event) {
return this.events[event]
}
addListener (type, listener) {
if (this.events[type]) {
if (this.maxListeners != 0 && this.events[type].length > this.maxListeners) {
return console.error(`该${type}事件类型的listteners超出限制,使用emitter.setMaxListeners() 来增加添加事件监听数量。`)
}
this.events[type].push(listener)
} else {
this.events[type] = [listener]
}
}
once (type, listener) {
//执行后立即销毁
let wrapper = (...rest) => {
listener.apply(this, rest)
this.removeListener(type, wrapper)
}
this.addListener(type, wrapper)
}
removeListener (type, listener) {
if (this.events[type]) {
this.events[type] = this.events[type].filter(ev => {
ev != listener
})
//抛弃掉等于listener的
}
}
removeAllListener (type) {
delete this.events[type]
}
emit (type, ...rest) {
this.events[type] && this.events[type].forEach(listener => {
listener.apply(this, rest)
})
}
}
MyEvents.prototype.on = MyEvents.prototype.addListener
module.exports = MyEvents复制代码