发布-订阅模式

161 阅读2分钟

什么是发布-订阅模式

发布订阅模式(Publish-Subscribe Pattern)是一种软件设计模式,用于实现解耦合的消息传递系统。在这种模式中,消息的发送者(发布者)不会直接将消息发送给特定的接收者(订阅者),而是通过一个称为消息代理(或消息中间件)的中介来传递消息。

在发布订阅模式中,发布者和订阅者之间不存在直接的耦合关系。发布者负责发布消息,而订阅者负责订阅感兴趣的消息类型。当有新的消息发布时,消息代理会将消息传递给所有订阅了相关消息类型的订阅者。

这种模式的一个常见应用场景是事件驱动架构,其中组件之间的通信通过消息传递来实现。发布者可以发布各种类型的事件,而订阅者可以选择订阅他们感兴趣的事件类型。这样,发布者和订阅者可以独立地演化和扩展,而不会影响彼此。

举个例子来说明发布订阅模式

假设有一个新闻网站,它需要将新闻内容传递给订阅了相关类别的用户。新闻网站可以作为发布者,将不同类别的新闻发布到消息代理中。而用户可以作为订阅者,选择订阅自己感兴趣的新闻类别。当新的新闻发布时,消息代理会将相关新闻传递给所有订阅了该类别的用户,使他们能够及时获取到感兴趣的内容。

如何实现发布-订阅模式

首先我们需要一个集中的消息调度中心来存放事件(代码中用key表示)。

订阅者订阅的事件会被注册到调度中心。

发布者发布事件后,调度中心收到提示会自动发送给订阅者。

  • 创建EventEmitter类。

  • cache用来存放事件。

  • on方法接受订阅者的订阅,并存储在cache中。

  • emit方法将cache中存放的函数全部执行,完成了发布流程。

完整代码

class EventEmitter {
    
    constructor() {
        this.cache = new Map()
    }
    
    on(key,callback){
        this.cache.has(key) ? this.cache.get(key).add(callback) : this.cache.set(key,new Set([callback]))
    }
    
    emit(key,...args){
        this.cache.has(key) && this.cache.get(key).forEach(callback=>{
            callback(...args)
        })
    }
    
    off(key,callback){
        if(!this.cache.has(key))    return
        if(callback)
            this.cache.get(key).delete(callback)
        else
            this.cache.delete(key)
    }

    once(key,callback){
        const fn = (...args) =>{
            callback(...args)
            this.off(key,fn)
        }
        this.on(key,fn)
    }
    
}


const e = new EventEmitter()

e.on('type',(...args)=>{
    console.log(args)
})

e.emit('type',1,2,3)