JavaScript之发布订阅模式

发布订阅模式

发布订阅模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。通过它,不必定时的去查询监听对象的状态是否发生改变。

在发布订阅模式中,我们经常定义一个事件中心来管理所有事件的发布和订阅。这也是和观察者模式最主要的区别。

观察者模式中只有两个角色,观察者和被观察者,两者之间存在一定的耦合关系。发布订阅模式,则有三个角色,发布者、订阅者和事件中心。事件中心可以避免发布者和订阅者之间的依赖关系,它一方面从发布者处接收事件,一方面向订阅者发布事件。

观察者模式:
 ╭─────────────╮  Fire Event  ╭──────────────╮
 │             │─────────────>│              │
 │   Subject   │              │   Observer   │
 │             │<─────────────│              │
 ╰─────────────╯  Subscribe   ╰──────────────╯

发布订阅模式:
 ╭─────────────╮                 ╭───────────────╮   Fire Event   ╭──────────────╮
 │             │  Publish Event  │               │───────────────>│              │
 │  Publisher  │────────────────>│ Event Channel │                │  Subscriber  │
 │             │                 │               │<───────────────│              │
 ╰─────────────╯                 ╰───────────────╯    Subscribe   ╰──────────────╯

下面是一个事件中心的实现:

const Event = (function () {
    const clientList = {}

    const listen = function (key, fn) {
        if ( !clientList[key] ) {
            clientList[key] = []
        }
        clientList[key].push( fn )
    }

    const trigger = function () {
        const key = Array.prototype.shift.call( arguments )
        const fns = clientList[key]
        if (!fns || fns.length === 0) {
            return 
        }
        for (let i = 0, listener;listener = fns[i++];) {
            listener.apply(this, arguments)
        }
    }

    const remove = function (key, fn) {
        const fns = clientList[key]
        if (!fns || fns.length === 0) {
            return
        }
        const index = fns.indexOf(fn)
        if (index !== -1) {
            fns.splice(index, 1)
        }
    }

    return {
        listen,
        trigger,
        remove
    }
})()

function onMessage1() {
    console.log('message 1')
}
function onMessage2() {
    console.log('message 2')
}

Event.listen('message', onMessage1)
Event.listen('message', onMessage2)

Event.trigger('message')
// message 1
// message 2

Event.remove('message', onMessage1)
Event.trigger('message')
// message 2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值