Skip to content

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

@forzys

Description

@forzys

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

发布订阅者模式(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
    }  
})() 

  • 代码不够健壮等待修改

Metadata

Metadata

Assignees

No one assigned

    Labels

    技术技能相关

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions