发布订阅模式
发布订阅这模式有三个主体:
发布主体:发布消息,也就是调用Event对象的emit()函数
订阅主体:订阅消息,使用on进行订阅,订阅的时候指定订阅处理函数fn
媒介主体:也就是Event对象,维护发布主体与订阅主体之间的关系,当订阅者订阅消息的时候,对订阅者的信息进行收集,保存到一个数组arr里面,当发布主体进行发布消息,也就是触发emit事件的时候,一次循环arr,循环所有的订阅者信息进行执行。这就实现了多个订阅者订阅同一消息,当消息发布的时候,所有的订阅者都会收到通知,即发布订阅模式。
const fs = require('fs');
var Event={
arr:[],
//订阅函数
on(fn){
this.arr.push(fn);
},
//发布消息,发布消息的时候粗发订阅者
emit(data){
this.arr.forEach(fn=>{
fn(data);
})
}
}
Event.on(function(data){
console.log("订阅者1收到信息:"+data)
})
Event.on(function(data){
console.log("订阅者2收到信息:"+data)
})
fs.readFile('./a.txt', function (err, data) {
if(!err){
Event.emit(data.toString());
}
});
fs.readFile('./b.txt', function (err, data) {
if(!err){
Event.emit(data.toString())
}
});
执行结果:
订阅者1收到信息:{
name:"sunshine",
age:23
}
订阅者2收到信息:{
name:"sunshine",
age:23
}
订阅者1收到信息:{
name:"mengfan",
age:22
}
订阅者2收到信息:{
name:"mengfan",
age:22
}
观察者模式
观察者模式是基于发布订阅者模式的。
Subject为被观察者,被观察者通过调用setState来实现自身状态的改变,setState处理被观察者的数据之后,会通知所有的观察者,通过observers的forEach循环进行通知。
Observer为观察者,要与被观察者进行绑定,registerObserver提供了观察者与被观察者绑定的实现,这与发布订阅模式的on很类似。并且绑定的时候,被观察者要记录所有观察者的基本信息,保存在自己的属性observers数组中,
//被观察者
class Subject {
constructor() {
this.state={};
this.observers=[];
}
registerObserver(observer){
this.observers.push(observer);
}
setState(newState){
this.state=newState;
this.observers.forEach(observer=>{
console.log(observer.name+"更新了")
observer.update(newState);
})
}
}
//观察者
function Observer(name){
this.name=name;
this.update=(newsTate)=>{
console.log(newsTate);
}
}
var subject=new Subject();
var observer=new Observer("观察者1");
var observer2=new Observer("观察者2");
subject.registerObserver(observer);
subject.registerObserver(observer2);
subject.setState({name:"更新状态1"});
subject.setState({name:"更新状态2"});
执行结果:
观察者1更新了
{ name: '更新状态1' }
观察者2更新了
{ name: '更新状态1' }
观察者1更新了
{ name: '更新状态2' }
观察者2更新了
{ name: '更新状态2' }
发布订阅模式和观察者模式的区别:
发布订阅模式和观察者模式之间的区别主要在于调度的地方不同。
发布订阅模式属于广义上的观察者模式
观察者和被观察者,是松耦合的关系 发布者和订阅者,则完全不存在耦合