消息发布与订阅 原理
消息发布与订阅是一种组件通讯,在 vue 和 react 中 能够简化组件通讯,能够像组件订阅消息和接收消息
1.如何实现
首先得明白事件的三大准则:事件源
,事件状态
,事件处理者
事件源就是事件源头,也就是事件发布者,一般用 on
关键字代替;事件状态,或者是这个事件是否有效,一般通过 off
来甄别这个事件是否有效;最后就是事件的接收者,用 emit
关键字
再了解三大准则的基础上,还得知道一个名词 事件池,在一个正真的企业级项目里面,会多次使用消息订阅与发布,多次消息的订阅 则称为 事件池(多个事件的集合)
下面,我们通过 微信公众号
用户的订阅与取消来模拟我们的订阅与发布
2.明确需求
微信公众号为 人民日报
,湖北日报
,陕西日报
- 用户
A
关注公众号 人民日报 - 用户
B
关注公众号 湖北日报 - 用户
C
关注公众号 人民日报 - 用户
C
取消关注 人命日报 C
取消了人民日报关注后,人民日报 再度发布消息,看用户C
是否可以收到消息
3.代码实现
具体代码实现如下:
class Sub {
constructor(){
// 事件池:接收用户的订阅并进行存储
this.list = {}
}
// 用户订阅: name => 订阅日报的名字 userid => 订阅日报用户的名称 fn => 用户的回调函数,用来监听日报发布的内容
on(name, userid, fn){
if(!(this.list[name] instanceof Array)) {
this.list[name] = []
}
this.list[name].push({ userid, fn })
}
// 日报发布消息: name => 日报名称 content => 日报发布的内容
emit(name, content){
this.list[name].forEach(ite => {
ite.fn(content)
})
}
// 取消关注: name => 取消关注的日报 userid => 用户
off(name, userid){
this.list[name].forEach((ite,index)=>{
if(ite.userid === userid){
this.list[name].splice(index, 1)
}
})
}
}
let sub = new Sub()
// 用户 A 订阅 人民日报
sub.on('人民日报', 'A', function(content){
console.log('A关注了人民日报',content)
})
// 用户 B 订阅 湖北日报
sub.on('湖北日报', 'B', function(content){
console.log('B关注了湖北日报',content)
})
// 用户 C 订阅 湖北日报
sub.on('湖北日报', 'C', function(content){
console.log('C关注了湖北日报',content)
})
// 人民日报发布消息
sub.emit('人民日报', '人民日报内容1')
sub.emit('湖北日报', '湖北日报内容2')
sub.off('湖北日报', 'C')
sub.emit('湖北日报', '湖北日报内容3')