什么是发布订阅模式?
在软件架构中,发布订阅是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者)。而是将发布的消息分为不同的类别,无需了解哪些订阅者(如果有的话)可能存在。同样的,订阅者可以表达对一个或多个类别的兴趣,只接收感兴趣的消息,无需了解哪些发布者(如果有的话)存在。
怎样实现一个最简发布订阅?
发布订阅里其实只有 3 个重要的东西:
- 一个数组存订阅者
- 一个方法添加订阅者
- 一个方法通知订阅者
以下是一个最简发布订阅的实现,便于理解
function Subscribe(){
this.listenerArr = [] // 用来存订阅者
// 存订阅者的方法
this.addListener = (listener) => {
this.listenerArr.push(listener)
}
// 发布的方法
this.notify = (fn) => {
this.listenerArr.forEach((listener)=>{
fn(listener)
})
}
}
let s1 = new Subscribe() // 创建一个实例
s1.addListener('小明') // 小明订阅了
s1.addListener('小红') // 小红订阅了
s1.addListener('小蓝') // 小蓝订阅了
s1.notify((name)=>{
console.log(`${name}去吃饭`) // 让他们都去吃饭
})
s1.notify((name)=>{
console.log(`${name}去散步`) // 让他们都去散步
})
打印:
也可以这么理解,listenerArr相当于一个公众号的粉丝,addListener方法相当于用户关注了这个公众号,notify相当于这个公众号发布了一篇文章告诉粉丝去看。
扩展
你发现没有,上面的订阅者都是人,其实也可以是方法,比如这样写。
function Subscribe(){
this.listenerArr = [] // 用来存订阅者
this.addListener = (listener) => {
this.listenerArr.push(listener)
}
this.notify = (name) => {
this.listenerArr.forEach((listener)=>{
listener(name)
})
}
}
let s1 = new Subscribe() // 创建一个实例
s1.addListener((name) => {
console.log(`${name}去吃饭`)
})
s1.addListener((name) => {
console.log(`${name}去散步`)
})
s1.notify('小明')
打印:
总结
核心就是用一个数组存,一个方法添加,一个方法通知。
这些地方用到了发布订阅:Promise的原理实现,Vue里EventBus的$on和$off
题外话,怎样区分发布订阅和观察者模式:
观察者模式 在软件设计中是一个对象,维护一个依赖列表,当任何状态发生改变自动通知它们。
发布-订阅模式,消息的发送方,叫做发布者(publishers),消息不会直接发送给特定的接收者,叫做订阅者(Subscriber)。