发布-订阅模式
一、什么是发布-订阅模式
二、怎么实现发布-订阅模式
2.1. 设计发布-订阅模式api
2.1.1. 怎么处理发布以及订阅之间的关系
2.1.1. 怎么实现订阅
2.1.1. 怎么实现发布
2.2. 代码实现
typescript
class EventBus{
// 存储事件-动作的对应关系
private events: Map<string,any> = new Map();
constructor(events?: Map<string, Function>){
this.events = events || new Map();
}
/**
* 增加订阅事件,并向订阅事件中添加动作/方法
* @param event 事件类型
* @param fn 要添加的动作/方法
*/
on(event:string, fn:any): void{
const e = this.events.get(event);
if (!e) {
this.events.set(event, [fn]);
} else {
e.push(fn);
}
}
/**
* 删除对应的订阅事件
* @param event 要删除的订阅事件
*/
off(event:string): void{
this.events.delete(event);
}
/**
* 发布事件,所有订阅此事件的动作均可以获取到消息
* @param event 要发布的事件
* @param args 向动作/方法中要传递的数据
*/
emit(event: string, ...args: any[] ): void{
const e = this.events.get(event);
if (!e) {
return;
} else {
for (let i = 0; i < e.length; i++) {
e[i].apply({ key: 'this is key' }, args);
}
}
}
}
// 示例话
const eventBus = new EventBus();
// 订阅/监听『print-year』事件,待事件发布之后便可获取到事件传递来的参数
eventBus.on('print-year', (date: Date) => {
console.log(`我关注的是当前年份:${date.getFullYear()}`);
})
eventBus.on('print-month', (date: Date) => {
console.log(`我关注的是当前月份:${date.getMonth()}`);
})
eventBus.on('print-date', (date: Date) => {
console.log(`我关注的是当前日期:${date.getDate()}`);
})
// 发布/触发事件并传递参数
eventBus.emit('print-year', new Date());
eventBus.emit('print-month', new Date());
eventBus.emit('print-date', new Date());
// 取消订阅『print-year』事件,对应事件再次发布不会收到信息
eventBus.off('print-year');
// 发布/触发事件并传递参数
eventBus.emit('print-year', new Date());
eventBus.emit('print-month', new Date());
eventBus.emit('print-date', new Date());