发布-订阅模式

51 阅读2分钟

发布-订阅模式又称观察者模式,生活中常见的例子比如订阅一个jy的专栏,等到更新的那一天,发布给所有订阅的对象。

实际上js的事件处理、vue2、vue3以及react-router、redux等的思想,都用到了发布订阅模式

/**
 *  - 发布者会给订阅者提供一个方法以便于订阅某些事件发生时要做的事情
    - 发布者可以通过触发一些操作来告知订阅者订阅已经到来,可以去做对应的后续处理
    - 当某个订阅者不想在订阅的时候可以进行订阅的取消
 */
class Observer {// 发布订阅模式(观察者模式),
    obj = {}

    on(event, callback) { //发布者通过on事件,触发event发生时 执行callback回调
        if (!this.obj[event]) {//由于订阅同一件事的人不止有一个,这里进行判断,并将订阅的事件和回调放进obj对象中
            this.obj[event] = [callback]
        } else {
            this.obj[event].push(callback)
        }
    }
    trigger(event) {//事件触发时,通知每一个订阅此事件的订阅者 (事件触发时,在obj对象中找到此事件,属性值数组 循环执行每个回调函数)
        const subscribers = this.obj[event] || []
        subscribers.forEach(cb => cb())
    }
    remove(event, subscriber) {//订阅者取消订阅(event:事件名,subscriber:回调)
        const subscribers = this.obj[event] || []
        const index = subscribers.findIndex(el => el === subscriber)
        if (index >= -1) {
            subscribers.splice(index, 1)
        }
    }
}
/**
 * 发布者触发了事件,触发一次,就会向obj对象中一个key(事件名)的value数组push一个回调 
 * 触发后,订阅此事件的人就会得到通知,从obj中寻找此事件名,并循环value数组执行回调来通知所有订阅此事件的人
 */

const person = new Observer()
const listen = () => {
    console.log('点击了')
}
person.on('点击', listen)
person.on('移动', () => {
    console.log('移动了')
})
person.on('点击', () => {
    console.log('点击了')
})
person.trigger('点击')
//  person.trigger('移动')
person.remove('点击', listen)

console.log('取消其中一个订阅')
person.trigger('点击')

发布订阅模式引入了一个发布者(或发布者/调度中心)的概念,发布者充当了中介者的角色。

发布者负责管理事件通知,而订阅者只需订阅感兴趣的事件,而不需要直接与发布者耦合。发布者在事件发生时将通知所有订阅者。

这种模式允许更灵活的通信方式,订阅者可以订阅和取消订阅特定类型的事件,而不需要知道发布者的存在。