(部分内容来自javascript模式与javascript设计模式)
观察者模式:
function Publisher(){
this.subscribers = [];
}
Publisher.prototype.deliver = function(data){
this.subscribers.forEach(
function(fn){
fn(data);
});
return this;
};
给予订阅者订阅的能力:
Function.prototype.subscribe = function (publisher){
var that = this;
if( !publisher.subscribers.some(
function(el){
return el === that;
}
) ) {publisher.subscribers.push(this);
}
return this;
};
关键是subscribers的some函数,以回调函数为参数,再把元素作为回调函数参数,如果有一个元素返回true那么some函数结果为true;
如果false则把元素放入到publisher的数据元素中;
给予订阅者退订的能力:
Function.prototype.unsubscribe = function(publisher){
var that = this;
publisher.subscribers = publisher.subscribers.filter(
function(el){
return el !== that;
});
return this;
};
通过数据的filter函数来过滤出数组元素;
以上观察者模式是通过发布者deliver, 而订阅者自己去订阅来实现的;
现在换一种方式通过发布者主动发布,订阅以及退订来实现;
var publisher = {
subscribers: {
any: []
},
subscriber: function(fn, type){
type = type || 'any';
if ( typeof this.subscribers[type] === "undefined" ){
this.subscribers[type] = [];
}
if( !this.subscribers[type].some(function(el){
return el === fn;
}){
this.subscribers[type].push(fn);
}
return this;
},
unsubscribe: function(fn, type){
type = type || 'any';
var subscribers = this.subscribers[type];
this.subscribers[type] = subscribers.filter(
function(el) {
return el !== fn;
});
/* var max = subscribers.length, i;
for( i = 0; i < max; ++i )
{
if( subscribers[i] === fn )
{ subscribers.splice(i, 1);break;}
}
*/
return this;
},
deliver: function( data, type){
type = type||'any';
var subscribers = this.subscribers[type],
i, max = subscribers.length;
for( i = 0; i < max; ++i )
{
subscribers[i](data);
}
/* subscribers.forEach(function(fn){fn(data);});*/
return this;
}
}
这样,我们可以通过一个makePublisher()函数来转换一个发布者:
function makePublisher(o){
var i;
for( i in publisher){
if(publisher.hasOwnProperty(i) && typeof publisher[i] === "function" ) {
o[i] = publisher[i];
}
}
o.subscribers = {any:[]};
}