美文网首页让前端飞Web 前端开发
发布\订阅模式(自定义事件)

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

作者: Hya | 来源:发表于2018-01-15 20:59 被阅读35次

    发布\订阅模式:

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

    这里是一个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 发布消息, 触发对应频道的所有回调函数,并将数据作为回调函数的参数 传给了订阅者

    相关文章

      网友评论

        本文标题:发布\订阅模式(自定义事件)

        本文链接:https://www.haomeiwen.com/subject/hkbroxtx.html