SubScribe即發佈訂閱模式,在工作中有著廣泛的應用,比如跨組件通信,微前端系統中跨子應用通信等等。 以下是一個簡易的實現: 訂閱 初始化時可限制類型 發佈 限制類型是為了讓訂閱者和發佈者知道預製了哪些類型,避免使用了一些對方不知道的類型。 type Subscriber<T> = (param ...
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
});