全局的發佈/訂閱對象
發佈/訂閱模式可以用一個全局的 Event 對象來實現,訂閱者不需要了解消息來自哪個發佈者,發佈者也不知道消息會推送給哪些訂閱者,Event 作爲一個類似“中介者” 的角色,把訂閱者和發佈者聯繫起來。
/** * 統一消息管理, 將消息發送給所有訂閱這個消息類型的模塊 * 採用 訂閱/發佈(觀察者) 這種設計模塊式開發 */ class MsgCenter { topicSubsMap = new Map(); uuid = 0; _getUUID() { return ++this.uuid; } /** * 事件發佈 * @param topic * @param resultObj */ publish(topic: string, resultObj: any) { if (!this.topicSubsMap.has(topic)) { return false; } let subscribers = this.topicSubsMap.get(topic) || []; subscribers.forEach((sub: object | any) => { sub.func(topic, resultObj); }); return true; } /** * 訂閱事件 * @param topic string | array * @param func function(topic, event) * @param uuid * @returns {*|number} */ subscribe(topic: string | string[], func: (topic: string, event: any) => any, uuid: number) { uuid = uuid || this._getUUID(); if (Array.isArray(topic)) { topic.forEach(item => { this.subscribe(item, func, uuid); }); return uuid; } if (!this.topicSubsMap.has(topic)) { this.topicSubsMap.set(topic, []); } this.topicSubsMap.get(topic).push({ token: uuid, func: func }); return uuid; } unsubscribe(token: any) { for (let subs of this.topicSubsMap.values()) { for (let i = 0; i < subs.length; i++) { if (subs[i].token == token) { subs.splice(i--, 1); } } } return false; } reset() { this.topicSubsMap.clear(); } } export default MsgCenter();
在代碼中的使用
// 訂閱者 class SubscribeComponent extends React.Component { constructor(props) { super(props); this.initEvent(); } initEvent = () => { this.token = msgCenter.subscribe('test_msgcenter', (topic, data) => { // data.data 取到的是發佈者發佈的數據 }); } componentWillUnmount() { msgCenter.unsubscribe(this.token); } } // 發佈者 class PublishComponent extends React.Component { handlePublish = () => { msgCenter.publish('test_msgcenter', { secuCode: record.secuCode }); } }