发布-订阅模式

1. 基本概念

发布-订阅模式是一种设计模式,用于实现对象之间的松散耦合。在这种模式下,发布者和订阅者之间并不直接通信,而是通过中介者来进行交流

  • 发布者publisher:负责发布事件或消息给中介者
  • 订阅者subscriber:订阅事件或消息,并在事件发生时被通知
  • 中介者(主题或事件总线):负责管理订阅者和发布者之间的关系,并在事件发生时通知所有订阅者

特点:

  • 松散耦合:通过中介者进行通信,系统更容易维护和扩展
  • 异步通信:发布者可以随时发布事件,订阅者可以在准备好时接收和处理这些事件
  • 多对多关系:一个事件可以有多个订阅者,一个订阅者可以订阅多个事件

2. 手写

class EventCenter {
    constructor () {
        // 事件中心
        this.events = {}
    }
    /**
     * 订阅事件
     * @param {string} eventName - 事件名称
     * @param {function} callback
     * @memberof EventCenter
     */
    subscribe (eventName, callback) {
        // 确保当前 eventName 在事件中心是唯一的
        if (!this.events[eventName]) {
            // 创建事件容器
            this.events[eventName] = []
        }
        // 存放事件
        this.events[eventName].push(callback)
    }
    /**
     * 取消订阅
     * @param {string} eventName
     * @param {function} callback
     * @return {*}
     * @memberof EventCenter
     */
    unSubscribe(eventName, callback) {
        // 事件中心里面没有这个事件
        if (!this.events[eventName]) {
            return new Error('not find event' + eventName)
        }
        // 只有事件名没有提供callback  删除对应事件名的所有订阅者(即事件数组)
        if (!callback) {
            delete this.events[eventName]
        } else {
            // 找到索引
            const index = this.events[eventName].findIndex((el) => el === callback)

            if (index !== -1) {
                return new Error('not find callback')
            }
            // 移除事件下的某个函数
            this.events[eventName].splice(index, 1)
            // 查看事件容器是否为空 如果为空就移除事件
            if (this.events[eventName].length === 0) {
                delete this.events[eventName]
            }
        }
    }

    /**
    * 触发事件
    * @param {string} eventName
    * @param {Array} args
    * @return {*}
    * @memberof EventCenter
    */
   dispatch (eventName, ...args) {
    if (!this.events[eventName]) {
        return new Error('not find event' + eventName)
    }
    // 触发事件
    this.events[eventName].forEach((el) => {
        el(...args) // 调用每个订阅者的回调函数
    })
   }
}

// Test
const eventCenter = new EventCenter()
// 订阅事件
eventCenter.subscribe('click', (x, y) => {
    console.log(`clicked at (${x}, ${y})`);
})
// 发布事件
eventCenter.dispatch('click', 10, 20) // output:clicked at (10, 20)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值