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
发布了80 篇原创文章 · 获赞 31 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/juzipidemimi/article/details/91349420
今日推荐