一、发布订阅者模式
- 订阅者
- 发布者
- 信号中心(事件中心) 存在一个信号中心,某个任务执行完成,就向信号中心发布一个信号,其他任务可以向信号中心订阅这个信号,从而知道什么时候自己可以开始执行,这就叫发布订阅者模式。
1. vue兄弟组件传值 理解发布订阅者模式 3个角色
// eventBus.js文件:事件中心
let eventBus = new Vue()
// 组件A文件:发布者
addTodo: function(){
// 发布消息
eventBus.$emit('add-todo',params)
}
// 组件B文件:订阅者
created(){
// 订阅消息
eventBus.$on('add-todo',function(){})
}
2. 发布订阅者的实现(信号中心)
class myEventEmitter {
constructor() {
// eventMap 用来存储事件和监听函数之间的关系
this.eventMap = {};
}
// type 这里就代表事件的名称 订阅事件
on(type, handler) {
// hanlder 必须是一个函数,如果不是直接报错
if (!(handler instanceof Function)) {
throw new Error("哥 你错了 请传一个函数");
}
this.eventMap[type] = this.eventMap[type] || [];
this.eventMap[type].push(handler);
}
emit(type, params) { // 发布事件
if (this.eventMap[type]) { // 处理事件(触发)
this.eventMap[type].forEach((handler, index) => {
handler(params);
});
}
}
off(type, handler) {
if (this.eventMap[type]) {
this.eventMap[type].splice(this.eventMap[type].indexOf(handler) >>> 0, 1);
}
}
}
- 代码测试
const myEvent = new myEventEmitter();
const testHandler = function (params) {
console.log(`test事件被触发了,testHandler 接收到的入参是${params}`);
};
myEvent.on("test", testHandler);
myEvent.emit("test", "newState");
二、观察者模式
观察者模式没有事件中心,只有发布者和订阅者,发布者需要知道订阅者的存在。在观察者模式中订阅者又叫做观察者。
- 观察者(订阅者) -- Watcher
- update():当事件发生时,具体要做的事情(例如:更新视图),是由发布者调用的
- 发布者(目标)-- Dep(记录所有的订阅者,当事件发生时通知所有订阅者)
- subs数组: 存储所有的观察者
- addSub(): 添加观察者
- notify(): 当事件发生,调用所有观察者的update()方法
1. 观察者模式
Dep dependency依赖: 收集依赖
// 发布者-目标
class Dep {
constructor(){
// 记录所有的订阅者
this.subs = []
}
// 添加订阅者
addSub(sub){
if(sub && sub.update){ // 必须包含update方法
this.subs.push(sub)
}
}
// 发布通知 触发所有订阅者的update
notify(){
this.subs.forEach(sub => {
sub.update()
})
}
}
// 订阅者-观察者
class Watcher {
update(){
console.log('update')
}
}
- 测试
let dep = new Dep()
let watcher = new Watcher()
dep.addSub(watcher) // 订阅
dep.notify() // 发布
三、区别
观察者没有事件中心。
- 发布订阅者模式由统一调度中心调度,因此订阅者和发布者不知道对方的存在。
- 观察者模式是由具体目标调度,比如当事件触发,Dep发布者就会去调用观察者的方法,所以观察者的订阅者与发布者之间存在依赖的。
观察者
当发布者Dep中数据发生变化的时候,会调用自己的notify方法通知所有的订阅者(调用订阅者Watcher的update方法),订阅者Watcher需要调用Dep的addSub方法订阅。发布者Dep内部记录了所有的观察者(subs),发布者和订阅者之间存在相互依赖的关系。
发布订阅者
多了一个事件中心,通过 事件中心隔离了发布者和订阅者。兄弟组件之间的传值。