定义:发布-订阅模式
Publish/Subscribe pattern和Observer pattern和类似,都是Observer注册,subject分布通知,但是Publish/Subscribe pattern多了个事件管道(event channel)用来集中处理监听的事件
观察者模式
观察者是一种 包含一系列依赖于主体(subject)的观察者(observers),自动通知它们变化的内容的设计模式,通俗来说就是一个对象(称为subject)维持一系列依赖于它的对象(称为observer),将有关状态的任何变更自动通知给它们(观察者)
区别
image如上图所示在观察者模式中,观察者是知道Subject的,Subject一直保持对观察者进行记录。然而,在发布订阅模式中,发布者和订阅者不知道对方的存在。它们只有通过消息代理进行通信。
代码实现例子
观察者模式
//观察者列表
function ObserverList(){
this.observerList = [];
}
ObserverList.prototype.add = function( obj ){
return this.observerList.push( obj );
};
ObserverList.prototype.count = function(){
return this.observerList.length;
};
ObserverList.prototype.get = function( index ){
if( index > -1 && index < this.observerList.length ){
return this.observerList[ index ];
}
};
ObserverList.prototype.indexOf = function( obj, startIndex ){
var i = startIndex;
while( i < this.observerList.length ){
if( this.observerList[i] === obj ){
return i;
}
i++;
}
return -1;
};
ObserverList.prototype.removeAt = function( index ){
this.observerList.splice( index, 1 );
};
//目标
function Subject(){
this.observers = new ObserverList();
}
Subject.prototype.addObserver = function( observer ){
this.observers.add( observer );
};
Subject.prototype.removeObserver = function( observer ){
this.observers.removeAt( this.observers.indexOf( observer, 0 ) );
};
Subject.prototype.notify = function( context ){
var observerCount = this.observers.count();
for(var i=0; i < observerCount; i++){
this.observers.get(i).update( context );
}
};
//观察者
function Observer(){
this.update = function(){
// ...
};
}
发布-订阅模式
//发布订阅模式
class EventEmiter {
constructor() {
//维护一个对象
this._events = {};
}
on(eventName, callback) {
if (this._events[eventName]) {
//如果有就放一个新的
this._events[eventName].push(callback);
} else {
//如果没有就创建一个数组
this._events[eventName] = [callback];
}
}
emit(eventName, ...rest) {
if (this._events[eventName]) {
//循环一次执行
this._events[eventName].forEach(item => {
item.apply(this, rest);
});
}
}
removeListener(eventName, callback) {
if (this._events[eventName]) {
//当前数组和传递过来的callback相等则移除掉
this._events[eventName] = this._events[eventName].filter(item => item !== callback);
}
}
once(eventName, callback) {
function one() {
//在one函数运行原来的函数,只有将one清空
callback.apply(this, arguments);
//先绑定 执行后再删除
this.removeListener(eventName, one);
}
this.on(eventName, one);
//此时emit触发会执行此函数,会给这个函数传递rest参数
}
}
class Man extends EventEmiter {}
let man = new Man();
function findGirl(a) {
console.log(a + '找新的女朋友');
}
function saveMoney(b) {
console.log(b + '省钱');
}
man.on('失恋', findGirl);
// man.on('失恋', findGirl); //失恋 ,绑定一个函数方法
man.on('失恋', saveMoney); //失恋 ,绑定一个函数方法
// man.removeListener('失恋', saveMoney); //移除一个函数方法
man.emit('失恋', { a: 1, b: 3 });
//绑定一次,触发多次,也只执行一次。触发后一次将数组中的哪一项删除掉下次触发就不会执行
网友评论