js 发布订阅模式实现

1、简单版

/**
 * 发布订阅模式
 */
class PublishSubscribePattern {
    constructor() {
        // 消息映射
        this.msgMap = {};
    }
    // 发布
    publish(name, param) {
        const msg = this.msgMap[name];
        if (msg) {
            msg.subscribes.forEach(subscribe => {
                subscribe.callback(param);
            });
        } else {
            console.log('无人订阅此消息:', name, param);
        }
    }
    // 订阅
    subscribe(name, callback) {
        const msg = this.msgMap[name];
        if (msg) {
            msg.subscribes.push({callback});
        } else {
            this.msgMap[name] = {
                name,
                subscribes: [{callback}]
            }
        }
    }
}

使用

const event = new PublishSubscribePattern();
event.publish('news', 'this is news 1');
event.subscribe('news', (param) => {
    console.log('get news:', param);
});
event.publish('news', 'this is news 2');

 

源码

/**
 * 发布订阅模式
 */
class PublishSubscribePattern {
    constructor() {
        // 消息映射
        this.msgMap = {};
    }
    // 发布
    publish({name, param, publisher}) {
        const msg = this.msgMap[name];
        if (msg) {
            if (!publisher)  {
                throw new Error('未注册发布人:' + name);
            } else if (publisher === 'all') {
                msg.subscribes.forEach(e => e.callback(param));
            } else {
                let beAccept = false;
                msg.subscribes.forEach(e => {
                    if (e.publisher === publisher) {
                        beAccept = true;
                        e.callback(param);
                    }
                });
                if (!beAccept) {
                    console.log('无人订阅你的消息:', name, param);
                }
            }
        } else {
            console.log('无人订阅此消息:', name, param);
        }
    }
    // 订阅
    subscribe({name, publisher}, callback) {
        const msg = this.msgMap[name];
        if (msg) {
            msg.subscribes.push({
                publisher,
                callback
            });
        } else {
            this.msgMap[name] = {
                name,
                subscribes: [{
                    publisher,
                    callback
                }]
            }
        }
    }
}

  

使用

const event = new PublishSubscribePattern();
event.publish({name: 'news', param: 'this is news 1', publisher: 'weather'});

event.subscribe({name: 'news', publisher: 'weather'}, (param) => {
    console.log(`get news from weather:`, param);
});

event.publish({name: 'news', param: 'this is news 2', publisher: 'weather'});
event.publish({name: 'news', param: 'this is news of newspaper', publisher: 'newspaper'});

/*
无人订阅此消息: news this is news 1
get news from weather: this is news 2
无人订阅你的消息: news this is news of newspaper
*/

  

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_34574204/article/details/130886249
————————————————
版权声明:本文为CSDN博主「大莲芒」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_34574204/article/details/130886249

posted @ 2023-09-13 11:14  男孩亮亮  阅读(141)  评论(0编辑  收藏  举报