Events-发布订阅
TIP
Node的事件模块为events,内部实现了一个发布订阅模式
1、继承方式
Child.prototype = Object.create(Parent.prototype)
Child.prototype.__proto__ = Parent.prototype
Object.setPrototypeOf(Child.prototype ,Parent.prototype)
Child extends Parent
2、使用方法
const EventEmitter = require('events');
const util = require('util');
// 1、定义子类对象
function Personal() {}
// 2、继承父类原型方法
util.inherits(Personal, EventEmitter);
let personal = new Personal();
// 监听绑定的事件名称
personal.on('newListener',function (type) {
console.log(type);
})
// 3、增加订阅方法
personal.on('test', function(...args) {
console.log(...args);
});
// 4、增加发布方法
personal.emit('test', 1, 2, 3);
// 5、订阅一次的方法
personal.once('test1', function(...args) {
console.log(...args);
});
personal.emit('test1', 1, 2, 3);
personal.emit('test1', 1, 2, 3);
// 6、关闭方法
const test2 = () => {
console.log('test2');
}
personal.on('test2', test2);
personal.off('test2', test2)
personal.emit('test2');
3、原理
- on 订阅
- emit 发布
- once 订阅一次
- off 删除
// 1、定义事件类
function EventEmitter() {
this._events = {}
}
// 2、订阅
EventEmitter.prototype.on = function(eventName, callback) {
// 如果没有就创建一个
if (!this._events) {
this._events = Object.create(null);
}
// 当前绑定的事件 不是newListener事件就触发newListener事件
if(eventName !== 'newListener'){
this.emit('newListener',eventName)
}
// 用数组存储回调函数
if (this._events[eventName]) {
this._events[eventName].push(callback);
} else {
this._events[eventName] = [callback];
}
}
// 发布
EventEmitter.prototype.emit = function(eventName, ...args) {
if (!this._events) return;
if (this._events[eventName]) {
// 依次遍历执行回调函数
this._events[eventName].forEach(fn => fn(...args));
}
}
// 3、订阅一次
EventEmitter.prototype.once = function(eventName, callback) {
// 切片编程
const once = (...args) => {
// 先执行原有的回调函数
callback(...args);
// 然后删除绑定
this.off(eventName, once)
}
// 用来标识这个once是谁的
once.l = callback;
// 订阅
this.on(eventName, once);
}
// 4、删除
EventEmitter.prototype.off = function(eventName, callback) {
if (!this._events) return;
// 过滤callback和once函数
this._events[eventName] = this._events[eventName].filter(fn => {
fn != callback && fn.l != callback
})
}
module.exports = EventEmitter