发布者订阅者模式相比于观察者模式多了一层事件调度中心。主要有发布事件,触发事件,删除事件等功能。
ES5原型写法
function EventBus() {
//定义一个事件容器
this.eventList = {};
//事件添加方法,参数有事件名和事件方法
EventBus.prototype.listen = function (event, callback) {
//判断有没有事件容器,没有则创建一个新事件容器
if (!(event in this.eventList)) {
this.eventList[event] = []
};
this.eventList[event].push(callback);
}
//触发事件 两个参数(事件名,参数)
EventBus.prototype.emit = function (event, ...args) {
//若没有注册事件则抛出错误
if (!(event in this.eventList)) {
throw new Error('未注册事件')
}
//触发事件
this.eventList[event].forEach(fn => { fn(...args) });
}
// 移除事件 (事件名 删除的方法 若无第二个参数则删除该事件的订阅和发布)
EventBus.prototype.delete = function (event, callback) {
if (!this.eventList[event]) {
throw new Error('无效事件')
}
if (this.eventList[event]) {
let index = this.eventList[event].indexOf(callback)
//有callback方法,删除方法
if (index !== -1) {
this.eventList[event].splice(index, 1)
}
//没有callback方法,直接删除事件
if (arguments.length === 1) {
delete this.eventList[event]
}
}
}
}
class写法
class EventBus {
constructor() {
this.eventList = {};
}
listen(event, cb) {
if (!this.eventList[event]) {
this.eventList[event] = [];
}
this.eventList[event].push(cb);
}
emit(event, ...args) {
if (!this.eventList[event]) {
throw Error('没有注册事件');
}
this.eventList[event].forEach(fn => fn(...args));
}
delete(event, cb) {
if (!this.eventList[event]) {
throw new Error('无效事件');
}
if (this.eventList[event]) {
const index = this.eventList[event].indexOf(cb);
if (index !== -1) {
this.eventList[event].splice(index, 1);
}
if (arguments.length === 1) {
delete this.eventList[event];
}
}
}
}
测试
let a = new EventBus();
let foo1 = function (msg) {
console.log(msg);
}
let foo2 = function (msg) {
console.log('fsaf');
}
let foo3 = function (a) {
console.log('1111');
}
a.listen('sayHi', foo1)
a.listen('haha', foo2)
a.listen('sayHi', foo3)
a.emit('sayHi', Math.random())
a.emit('sayHi', ['214214', '12312'])
a.emit('haha', 1241)
a.delete('sayHi', foo3)
console.log(`############################`)
a.emit('sayHi', Math.random())
a.emit('sayHi', ['214214', '12312'])
a.emit('haha', 1241)
记录记录!