Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

设计模式之发布订阅者模式 #9

Open
forzys opened this issue Jul 4, 2023 · 0 comments
Open

设计模式之发布订阅者模式 #9

forzys opened this issue Jul 4, 2023 · 0 comments
Labels
技术 技能相关

Comments

@forzys
Copy link
Owner

forzys commented Jul 4, 2023

发布订阅者模式是一种行为设计模式

发布订阅者模式(Publish-Subscribe pattern)是一种常见的设计模式,也被称为观察者模式(Observer pattern)。在这种模式中,发布者(Publisher)和订阅者(Subscriber)之间通过一个被称为事件总线(Event Bus)的中介者进行通信。当发布者发布一个事件时,事件总线会将该事件传递给所有订阅者,订阅者可以根据自己的需求选择性地接收和处理这些事件。

根据以上内容实现的发布订阅者模式代码

const EventBus = (function(){
    let topics = {}, offEvents ={}, uuid = 0;
 
    function subscribe (topic, callback, once) {
        /**
         * topic  被订阅的内容的key值
         * callback 订阅者传入的订阅事件
         * once 是否只订阅一次
         */

        uuid ++
        topics[topic] = topics[topic]
            ? [...topics[topic], { callback, uuid, once }]
            : [{ callback, uuid, once }]
        // 存在离线事件 则执行离线事件
        if(offEvents[topic]){
            publish(topic, ...offEvents[topic])
        }

        return uuid
    }

    function publish (topic, value) {
        /**
         * topic 被发布的内容的key值
         * value 发布者传入的订阅事件
         */
        if (topics[topic]) { 
            for (let i = 0; i < topics[topic].length; i++) {
                let item = topics[topic][i]
                item.callback(value); 
                // 只订阅一次 则执行之后销毁
                if (item.once) {
                    topics[topic].splice(i, 1)
                }
            }
            // 执行后将对应离线事件置空
            offEvents[topic] = null
        }else{
            // 先发布再订阅事件 则先存储为离线事件
            offEvents[topic] = [value]
        }
    }
 
    function unsubscribe(topic, callback){
        /**
         * topic 被取消订阅的内容的key值
         * callback 取消订阅者传入的订阅事件 | 订阅时返回的uuid | 默认取消所有订阅
         */
        if (topics[topic]) {
            let name = ''
            if(callback instanceof Function){
                name = 'callback'
            }
            if(typeof callback === 'number'){
                name = 'uuid'
            } 
            if(typeof callback === 'undefined'){
                name = 'undefined'
            }

            for (let i = 0; i < topics[topic].length; i++) {
                let fn = topics[topic][i][name] 
                if (fn === callback) {
                    fn ? topics[topic].splice(i, 1) : topics[topic].pop()
                }
            }   
        }
    }

    // 订阅一次 执行之后销毁
    function subscribeOnce(topic, callback){
        return subscribe(topic, callback, true)
    } 

    return {
        subscribe,
        publish,
        unsubscribe,
        subscribeOnce
    }  
})() 

  • 代码不够健壮等待修改
@forzys forzys added the 技术 技能相关 label Jul 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
技术 技能相关
Projects
None yet
Development

No branches or pull requests

1 participant