什么是发布订阅模式
-
我
关注
了一个视频博主,这就是一个订阅
过程。 -
视频博主
更新
了视频,所有关注了博主的人都会收到提醒,这就是一个发布
过程。
优点
- 解耦合:关注者想第一时间收到视频只要关注(
订阅
)即可。博主只需要关注更新(发布
)视频这一个动作即可。
巨极简版的发布订阅模式!!!
内容不完全,帮助大家快速对发布订阅模式有一个大致的认识
js
// publish 发布
// subscribe 订阅
// PubSub看作是调度中心
const PubSub = {
list: [],
// 发布方法
publish() {
this.list.forEach(item => item())
},
// 订阅方法
subscribe(callback) {
this.list.push(callback)
}
}
// 定义两个回调函数 表示订阅者
function demo1() {
console.log('demo1');
}
function demo2() {
console.log('demo2');
}
// 现在进行订阅操作
PubSub.subscribe(demo1)
PubSub.subscribe(demo2)
// 现在开始发布
PubSub.publish()
运行结果:
jsdemo1 demo2
- 上述代码存在一个问题:无法实现事件的细分
也就是说,无法实现一个用户名为a
的用户的订阅,也不能实现一个事件b
的发布。
上述的代码在发布的时候,直接一股脑从头把事件遍历到尾了。
极简代码的改进
那么怎么解决按类来进行事件的订阅和发布呢?
设想一下:现在有个用户a
,需要订阅一件事情b
。有一个用户c
需要订阅事件d
和e
。
那么list
的数组结构其实可以用对象
形式来做替代:一个名为a
的对象存在存储了属性b
。一个名为c
的对象存储了一个属性d
和e
自然而然地,那进行订阅
操作的时候,就需要传入两个参数了,你需要告诉调度中心
,你的名字是啥,然后传入一个回调函数
告诉调度中心
当事件发布的时候调度中心需要做什么
那么发布
的时候,自然也可以加一个参数,来表示我们要发布的是哪一个用户所订阅的内容。
改进后的代码如下:
js
const PubSub = {
// 换成对象
message: {},
// 发布方法
publish(type) {
if (!this.message[type]) {
return
}
this.message[type].forEach(item => item())
},
// 订阅方法
subscribe(type, callback) {
// 判断type是否存在
if (!this.message.type) {
this.message[type] = [callback]
} else {
this.message[type].push(callback)
}
}
}
function demoA() {
console.log('demoA');
}
function demoB() {
console.log('demoB');
}
PubSub.subscribe('A', demoA)
PubSub.subscribe('B', demoB)
// 发布操作
PubSub.publish('A')
PubSub.publish('B')
运行结果:
jsdemoA demoB
上述代码就实现了根据每一个用户订阅
的事件进行专门地发布
。
增加取消订阅功能
能订阅、能发布,下面再添加一个取消订阅的功能。 注意:取消订阅的时候,需要指定取消订阅的那个用户名,不然调度中心是不知道你要取消订阅哪一个用户的。
js
const PubSub = {
message: {},
publish(type) {
if (!this.message[type]) {
return
}
this.message[type].forEach(item => item())
},
subscribe(type, callback) {
if (!this.message.type) {
this.message[type] = [callback]
} else {
this.message[type].push(callback)
}
},
// 添加取消订阅的方法
// 注意 需要指定 type 以及对应的事件:callback
unsubscribe(type, callback) {
// 如果不存在该类型 直接返回
if (!this.message[type]) {
return
} else {
this.message[type] = this.message[type].filter(item => item != callback)
}
}
}
function demoA() {
console.log('demoA');
}
function demoB() {
console.log('demoB');
}
PubSub.subscribe('A', demoA)
PubSub.subscribe('B', demoB)
PubSub.publish('A')
PubSub.publish('B')
// 进行取消订阅
PubSub.unsubscribe('A', demoA)
console.log('我是华丽的分割线');
PubSub.publish('A')
PubSub.publish('B')
运行结果:
jsemoA demoB 我是华丽的分割线 demoB
总结
发布订阅模式中存在三个角色:订阅者
、发布者
、调度中心
。
订阅者
只负责订阅消息,发布者
只负责发布消息。实现了业务之间的解耦。发布者
负责总体的调度。
最后
这个模式使用的场景太多了,vue
的事件绑定就有使用到该设计模式。我所在的公司也有一个项目是基于发布订阅模式
的。
ps:本人正在学习写博客,如果写的不好还请见谅!!可以的话也可以提提建议我好改进!!大家一起进步啊😁