发布-订阅模式
CREATE: 2022-03-11 22:14:09
题目:请利用 Ts | Js 实现一个订阅-发布模式(或者称为发布-订阅模式) ( 简单😄 )
分析
注意区分 观察者模式
和 订阅-发布模式
,详见 观察者模式与订阅发布模式的区别
由下图可以发现,订阅-发布模式多了一个 中间人
,负责订阅和发布
题解
class PubCenter {
private subscribers: {
[type: string]: ((...args: any) => void)[]
} = {}
subscribe(type: string, fn: any) {
const topic = this.subscribers[type]
if (topic) {
topic.push(fn)
} else {
this.subscribers[type] = [fn]
}
}
publish(msg: any, type?: string) {
if (!type) {
Object.keys(this.subscribers).forEach((type) => {
this.publish(msg, type)
})
} else {
const topic = this.subscribers[type]
topic?.forEach((x) => x && x(`type:${type}, msg:${msg}`))
}
}
unsubscribe(type: string, fn: any) {
if (!type || !fn) return
const existIndex = this.subscribers[type]?.indexOf(fn)
if (existIndex != -1) {
this.subscribers[type].splice(existIndex, 1)
}
}
clear(type?: string) {
if (!type) {
this.subscribers = {}
} else {
this.subscribers[type] = this.subscribers[type] ? [] : undefined
}
}
}
使用
function main() {
const pubCenter = new PubCenter()
const fn1 = (msg) => {
console.log('[fn1 receive msg]:', msg)
}
const fn2 = (msg) => {
console.log('[fn2 receive msg]:', msg)
}
const fn3 = (msg) => {
console.log('[fn3 receive msg]:', msg)
}
pubCenter.subscribe('SMS', fn1)
pubCenter.subscribe('SMS', fn2)
pubCenter.subscribe('SMS', fn3)
pubCenter.subscribe('QQ', fn1)
pubCenter.publish('hello, everyone111')
console.log('[-----------unsubscribe fn2 SMS--------------]:')
pubCenter.unsubscribe('SMS', fn2)
pubCenter.publish('hello, everyone222')
console.log('[-----------clear all SMS--------------]:')
pubCenter.clear('SMS')
pubCenter.publish('hello, everyone333')
}
main()
输出
[fn1 receive msg]: type:SMS, msg:hello, everyone111
[fn2 receive msg]: type:SMS, msg:hello, everyone111
[fn3 receive msg]: type:SMS, msg:hello, everyone111
[fn1 receive msg]: type:QQ, msg:hello, everyone111
[-----------unsubscribe fn2 SMS--------------]:
[fn1 receive msg]: type:SMS, msg:hello, everyone222
[fn3 receive msg]: type:SMS, msg:hello, everyone222
[fn1 receive msg]: type:QQ, msg:hello, everyone222
[-----------clear all SMS--------------]:
[fn1 receive msg]: type:QQ, msg:hello, everyone333