实现发布订阅

571 阅读1分钟
class MessageCenter {
    subscribers = {}; // 记录各个订阅类型订阅者的randomKey
    subscribersCallback = {}; // 记录各个订阅类型订阅者的回调
    subscribe(key, callback) {
        // console.log('订阅了' + key);
        const randomKey = String(Math.random());
        if (!this.subscribers[key]) {
            this.subscribers[key] = [randomKey];
        } else this.subscribers[key].push(randomKey);
        if (!this.subscribersCallback[key]) this.subscribersCallback[key] = {};
        this.subscribersCallback[key][randomKey] = callback;
        // console.log('当前订阅者:', this.subscribers, this.subscribersCallback);
        return () => this.unsubscribe(key, randomKey)
    }
    unsubscribe(key, randomKey) {
        // console.log('取消订阅了' + key);
        if (!this.subscribers[key]) return;
        const deleteIndex = this.subscribers[key].findIndex(item => item === randomKey);
        if (deleteIndex === -1) return;
        this.subscribers[key].splice(deleteIndex, 1);
        delete this.subscribersCallback[key][randomKey];
        // console.log('当前订阅者:', this.subscribers, this.subscribersCallback);
    }
    publish(key, payload) {
        // console.log('收到了发布' + key);
        if (!this.subscribers[key]) return;
        this.subscribers[key].forEach(randomKey => {
            const callback = this.subscribersCallback[key][randomKey];
            if (typeof callback === 'function') {
                try {
                    callback(payload);
                }
                catch (e) {

                }
            }
        });
    }
}

const messageCenter = new MessageCenter();
const a = messageCenter.subscribe('buy', (payload) => {
  console.log(`a收到信息, ${ payload.name } price is ${ payload.price }`)
});
const b = messageCenter.subscribe('buy', (payload) => {
  console.log(`b收到信息, ${ payload.name } price is ${ payload.price }`)
});
messageCenter.publish('buy', {
  price: 100,
  name: '全家桶'
});
a(); // a取消订阅
messageCenter.publish('buy', {
  price: 13,
  name: '一对辣翅'
});

输出

"a收到信息, 全家桶 price is 100"
"b收到信息, 全家桶 price is 100"
"b收到信息, 一对辣翅 price is 13"