index.ts 文件
// @ts-nocheck
import { isDevEnv } from '@cxyx/foundation/utils/env'
import EventDesc from './event-desc'
type IEventType = new (...args: any[]) => EventDesc
type ISendEventListener = (eventName: string) => void
type ICommonFunc = (event: any) => void
type IListenerRef = { key: number; handler: ICommonFunc }
// 注册事件索引 | 注册事件回调 | 注册事件的描述类的实例
type ISubscribeRetVal = [number, ICommonFunc, IEventType]
export default class EventBus {
// 存储注册事件
private _eventListeners: Map<IEventType | EventDesc, Array<IListenerRef>> = new Map()
// 当前注册事件索引,用于取消事件
private _currentIndex: number = 0
private onSendEvent?: ISendEventListener
/**
* 订阅 Event
* @param {IEventType} event 消息类型
* @param {(event: T) => void} handler 响应方法
* @returns {ISubscribeRetVal | never} 注册事件索引 | 注册事件回调 | 注册事件的描述类的实例 | never
*/
public subscribe(event: IEventType, handler: ICommonFunc): ISubscribeRetVal | never {
if (isDevEnv && !handler) {
throw new Error('invaild handler')
}
this._currentIndex++
if (!this._eventListeners.has(event)) {
this._eventListeners.set(event, [{ key: this._currentIndex, handler: handler }])
} else {
;(this._eventListeners.get(event) as Array<IListenerRef>).push({ key: this._currentIndex, handler: handler })
}
return [this._currentIndex, handler, event]
}
/**
* 设置发送 Event 的监听
* @param {ISendEventListener} onSendEvent
*/
public setSendEventListener(onSendEvent: ISendEventListener): void {
this.onSendEvent = onSendEvent
}
/**
* @param eventName: 触发事件的名称
*/
public sendEvent<T extends EventDesc>(event: T): void {
if (!event?.constructor) return
const listenersList = this._eventListeners.get(event.constructor) as Array<IListenerRef>
if (listenersList?.length) {
listenersList.forEach((listener: IListenerRef) => {
listener.handler(event)
})
if (this.onSendEvent) {
this.onSendEvent(event.name)
}
}
}
/**
* 取消订阅 Event
* @param {[number, ICommonFunc]} unsubscribeParams
*/
public unsubscribe(unsubscribeParams: ISubscribeRetVal): void {
const currentSubscribePointIndex = unsubscribeParams[0]
const currentSubscribePointEventRef = unsubscribeParams[2]
if (this._eventListeners.has(currentSubscribePointEventRef)) {
const listeners = this._eventListeners.get(currentSubscribePointEventRef)
const reasonListener = listeners?.filter(listenerRef => listenerRef.key !== currentSubscribePointIndex) as Array<IListenerRef>
this._eventListeners = this._eventListeners.set(currentSubscribePointEventRef, reasonListener)
}
}
}
const eventBus = new EventBus()
export { eventBus }
README.md
基于 RxJS 实现的 Event 总线,使用方式如下:
* step 1: 根据业务场景,在合适的时机生成 EventBus 实例, 如在页面初始化时。
const eventBus = new EventBus();
// 设置发送 Event 的回调
eventBus.setSendEventListener(( apiName: string )=>{ console.log(send ${apiName} event
) });
* step 2: 继承 AbsEventDesc 定义一个Event。
class MyEventMsg extends AbsEventDesc {
public name = ‘MyEventMsg’;
// 根据需要自定义要传递的属性,属性修饰符为Public
public msg: string;
constructor(msg: string) {
super();
this.msg = msg;
}
}
* step 3: 在 Event 消费者处注册 Event 监听。
// 订阅消息
const subscription = eventBus.subscribe(MyEventMsg, (event: MyEventMsg) => {
// do something
});
// 取消订阅
eventBus.unsubscribe(subscription);
* step 4: 在 Event 生产者处发送 Event。
// 发送消息
eventBus.sendEvent(new MyEventMsg(‘hello’));
```