- A+
所属分类:Web前端
SubScribe即发布订阅模式,在工作中有着广泛的应用,比如跨组件通信,微前端系统中跨子应用通信等等。
以下是一个简易的实现:
- 订阅
- 初始化时可限制类型
- 发布
限制类型是为了让订阅者和发布者知道预制了哪些类型,避免使用了一些对方不知道的类型。
type Subscriber<T> = (param?: T) => void export default class SubScribe<P> { // 订阅数据仓库 public subscribers: Record<string, Subscriber<P>[]> = {}; // 可允许的事件类型 public types: undefined | string[] = undefined; constructor (types?: string []) { this.types = types; } // 订阅 subscribe (type: string, subscriber: Subscriber<P>) { const _types = this.types; if (_types && !_types.includes(type)) { console.warn(`创建订阅 ${type} 失败 ,订阅类型只允许 ${_types.join(',')} 这几种...`); return; } if (typeof subscriber !== 'function') { console.warn('创建订阅失败,第二个参数必须为函数类型'); return; } if (!this.subscribers[type]) { this.subscribers[type] = []; } this.subscribers[type].push(subscriber); } // 订阅一次,触发后自动取消订阅 subscribeOnce (type: string, subscriber: Subscriber<P>) { if (typeof subscriber !== 'function') { console.warn('创建订阅失败,第二个参数必须为函数类型'); return; } const wrap = (param?: P) => { subscriber(param); this.unSubscribe(type, wrap); }; this.subscribe(type, wrap); } // 取消订阅 unSubscribe (type: string, subscriber: Subscriber<P>) { if (this.subscribers[type]) { this.subscribers[type] = this.subscribers[type].filter(f => f !== subscriber); } } // 发布事件,触发订阅函数执行 publish (type: string, param?: P) { const _types = this.types; if (_types && !_types.includes(type)) { console.warn(`发布 ${type} 失败,发布类型只允许 ${_types.join(',')} 这几种...`); return; } if (this.subscribers[type]) { this.subscribers[type].forEach(f => { f(param); }); } } }
以下是一个使用案例
初始化并导出一个发布订阅实例(如果是微前端系统,则将该实例传给各个子应用),然后可以通过该实例进行跨对象的通信。
// 初始化 export const masterSubscribe = new SubScribe(['MICRO_CHILD_ROUTE_MOUNTED', 'MICRO_ACTION']); // 订阅 masterSubscribe && masterSubscribe.subscribe('MICRO_ACTION', (params) => { // 执行一些动作 }); // 发布 masterSubscribe.publish('MICRO_ACTION', { //...params });