现在网上很多文章都讲不清楚什么是发布/订阅和观察者模式,要不就是复制粘贴过来的,百度都能查处一大推一模一样的文章。很气愤!!!
那么我将根据自己的理解去解释发布/订阅和观察者模式,如果有大佬觉得不对,欢迎在评论区留下宝贵意见
发布/订阅模式
发布/订阅模包含:
- 发布者
- 订阅者
- 信号中心
假设你要买房子,但是你有没有房源信息,那么你会找到谁?你肯定会去问房屋中介,那么这个房屋中介就是一个信号中心。那么这个房子的主人也就是房东是一个发布者(publish),你或者其他需要买房的人就是订阅者(subscribe)。
那么在Vue是如何实现的呢?
// Vue 中使用方法
let vm = new Vue()
// 订阅者
vm.$on('change', () => {
console.log('change')
})
// 订阅者
vm.$on('change', () => {
console.log('change1')
})
// 发布者
vm.$emit('change')
以上就是 Vue 中使用的方法,通过$on方法来订阅change事件,通过$emit方法来发布change事件,那么订阅者获取到事件之后就会执行相对应的方法。这就是发布/订阅模式(publish-subscribe pattern )。接下来我们老模拟实现一个发布/订阅模式来加深印象
首选我们来分析下订阅/发布模式是如何实现的
- 定义一个类Vue(也可以是其他名称)
- 类里面有两个方法$on(订阅者)和$emit(发布者)
- $on方法里接受两个参数,一个是事件类型,另一个是执行的方法
- $emit方法里接受一个参数,事件类型
接下来根据我们分析的情况通过代码来模拟实现如下:
// 事件中心
class Vue {
constructor () {
// 创建一个空对象,结构是{ event: [function1, function2, ...] }
this.subs = Object.create(null)
}
// 定义$on方法(订阅者)event: 事件名称 handler: 需要执行的方法
$on (event, handler) {
// 匹配对应的事件,如果事件存在就取事件对应的值,否则就取空数组
this.subs[event] = this.subs[event] || []
// 找到对应的事件将值(函数)push到对应的事件值中
this.subs[event].push(handler)
}
// 定义$emit方法(发布者)
$emit(event) {
// 判断当前事件是否存在,存在执行对应值的方法
if(this.subs[event]) {
this.subs[event].forEach(handler => {
handler()
})
}
}
}
// 测试
let vm = new Vue()
vm.$on('change', () => {
console.log('change')
})
vm.$emit('change')
浏览器执行以上代码会发现控制台打印出'change',以上就是发布/订阅模式的实现方式
关注我后续我会继续更新观察者模式