发布\订阅模式(自定义事件)

发布\订阅模式:

软件架构中,发布-订阅是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者)。而是将发布的消息分为不同的类别,无需了解哪些订阅者(如果有的话)可能存在。同样的,订阅者可以表达对一个或多个类别的兴趣,只接收感兴趣的消息,无需了解哪些发布者(如果有的话)存在。 有着松耦合、可拓展性强等优点

这里是一个pub/sub的简单实现:

class EventEmitter {

    constructor(){

        //observers是一个对象,形式如下:
        // {
        //     chA: [fnA1, fnA2, ...],
        //     chB: [fnB1, fnB2, fnB3, ...]
        // }
        // 其中 chA,chB,对应不同频道, fn是每个频道 里面的回调函数
        // 订阅、发布: 其实就是往 observers 里面写入回调函数(fn), 以及遍历执行回调函数的过程(fn(arg))
        // 订阅 : on('foo', fn)表示 订阅了 频道 foo ,如果 foo频道有消息推送, 就触发回调函数
        // 发布: trigger('foo', 'hello')表示 发送一条消息 hello 到 foo 频道, 
        // 这样 订阅了 foo频道的所有 订阅者 都可以接收到 其数据

        
        this.observers = {}
    }

    on(channel, f) {
        let key = channel
        if (Array.isArray(this.observers[key])) {
            this.observers[key].push(f)
        } else {
            this.observers[key] = [f]
        }
    }

    trigger(channel, ...args) {
        let _observer = this.observers[channel]
        if (!_observer || _observer.length === 0) {
            return
        }
        for (let fn of _observer) {
            fn(...args)
        }
    }

    off(channel) {
        this.observers[channel] = null
    }
}

// 其使用 方式如下
var e = new EventEmitter()
e.on('a', (data) => {
    console.log('a data', data)
})
e.on('b', (data) => {
    console.log('b data', data)
})

e.trigger('a', 'hello')
e.trigger('b', {
    x: 2,
    y: 3
})
e.off('a')

结论:

发布\订阅模式的实现很简单, 主要有三部分构成:

  • 一个消息中心:observers 用于存储每个订阅的回调函数
  • 一个订阅函数: on 用于往 消息中心写入对应频道的监听回调函数
  • 一个发布函数:trigger 发布消息, 触发对应频道的所有回调函数,并将数据作为回调函数的参数 传给了订阅者
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容