实现eventEmmiter,发布-订阅 模式 (on, emit, off)
/*
* @Date: 2024-03-14 15:46:52
* @Description: Modify here please
*/
interface SubscribeEvent {
fn: Function;
once: boolean;
}
class EventEmmiter {
subscribes: Map<string, Array<SubscribeEvent>>;
constructor() {
this.subscribes = new Map();
}
addEvent(type: string, callback: Function, once: boolean = false) {
const sub = this.subscribes.get(type) || [];
sub.push({ fn: callback, once });
this.subscribes.set(type, sub);
}
/**
* 事件订阅
* @param type 订阅的事件名称
* @param callback 触发的回调函数
*/
on(type: string, callback: Function) {
this.addEvent(type, callback);
}
/**
* 发布事件
* @param type 发布的事件名称
* @param args 发布事件的额外参数
*/
emit(type: string, ...args: Array<any>) {
const sub = this.subscribes.get(type) || [];
const context = this;
sub.forEach(({ fn }) => {
fn.call(context, ...args);
});
const newSub = sub.filter((item) => !item.once);
this.subscribes.set(type, newSub);
}
/**
* 取消订阅
* @param type 取消订阅的事件名称
* @param callback 取消订阅的具体事件
*/
off(type: string, callback: Function) {
const sub = this.subscribes.get(type);
if (sub) {
const newSub = sub.filter(({ fn }) => fn !== callback);
this.subscribes.set(type, newSub);
}
}
// 只订阅一次
// 我们使用过发布-订阅都应该知道发布-订阅直接一次订阅,即这个订阅者只会被通知一次。下面,我们来增加这个操作。
// 思路:我们的订阅者需要具有once的属性,来进行判断,并且,在每一次emit后,我们需要把once事件清除。
once(type: string, callback: Function) {
this.addEvent(type, callback, true);
}
}
const eventEmmiter = new EventEmmiter();
// eventEmmiter.once('notice',() => {
// console.log('只订阅一次');
// })
// const publish = (a,b) => {
// const sum = a + b
// console.log(a,b+'两数之和为' + sum);
// }
// eventEmmiter.on('notice',publish);
// eventEmmiter.emit('notice',2,3);
// eventEmmiter.emit('notice',4,5);