您的位置:首页 > Web前端 > JavaScript

javascript设计模式-(发布-订阅模式)

2017-08-09 19:09 176 查看
var salesOffices={};//定义售楼处
salesOffices.clientList=[];//缓存列表,存放订阅者的回调函数
salesOffices.listen=function (fn) {//增加订阅者
this.clientList.push(fn);//订阅的消息添加进缓存列表
};
salesOffices.trigger=function(){//发布消息
for(var i=0,fn;fn=this.clientList[i++];){
fn.apply(this, arguments);//fn是发布消息时带上的参数
}
};
salesOffices.listen(function(price,squareMeter){
console.log(price);
console.log(squareMeter);
});
salesOffices.trigger(200000,88);


增加一个key,让订阅者只订阅自己感兴趣的消息。

var salesOffices={};//定义售楼处
salesOffices.clientList=[];//缓存列表,存放订阅者的回调函数
salesOffices.listen=function (key,fn) {
if(!this.clientList[key]){
this.clientList[key]=[];//如果还没有订阅过此类消息,该该类消息创建一个缓存列表
}
this.clientList.push(fn);//订阅的消息添加进缓存列表
};
salesOffices.trigger=function(){//发布消息
var key=Array.prototype.shift.call(argments),//取出消息类型
fns=this.clientList[key];//取出该消息对应的回调函数集合
if(!fns||fns.length===0){//如果没有订阅该消息,则返回
return false;
}
for(var i=0,fn;fn=this.clientList[i++];){
fn.apply(this, arguments);//arguments是发布消息时带上的参数
}
};
salesOffices.listen('squareMeter88',function(price){
console.log(price);
});
salesOffices.listen('squareMeter110',function(price){
console.log(price);
});
salesOffices.trigger('squareMeter88',200000);
salesOffices.trigger('squareMeter110',300000);


发布-订阅的通用实现

// 将发布-订阅功能提取出来,放在一个单独的对象里
var event={
clientList:[],
listen:function(key,fn){
if(!this.clientList[key]){
this.clientList[key]=[];
}
this.clientList[key].push(fn);
},
trigger:function(){
var key=Array.prototype.shift.call(arguments),
fns=this.clientList[key];
if(!fns||fns.length===0){
return false;
}
for(var i=0,fn;fn=fns[i++];){
fn.apply(this, arguments);
}
}
};

// 再定义一个installEvent函数,这个函数可以给所有的对象都动态安装发布-订阅功能
var installEvent=function(obj){
for(var i in event){
obj[i]=event[i];
}
};

// 测试
var salesOffices={};
installEvent(salesOffices);
salesOffices.listen('squareMeter88',function(price){
console.log(price);
})
salesOffices.trigger('squareMeter88',2000000);


取消订阅的事件

event.remove=function (key,fn) {
var fns=this.clientList[key];
if(!fns){
return false;
}
if(!fn){
fns&&(fns.length=0);
} else {
for(var l=fns.length-1;l>=0;l--){
var _fn=fns[l];
if(_fn===fn){
fns.splice(l,1);
}
}
}
};
var salesOffices={};
var installEvent=function(obj){
for(var i in event){
obj[i]=event[i];
}
}

installEvent(salesOffices);
salesOffices.listen('squareMeter88',fn1=function(price){ //小明订阅
console.log(price);
});
salesOffices.listen('squareMeter88',fn2=function(price){ //小红订阅
console.log(price);
});
salesOffices.remove('squareMeter88',fn1);//删除小明的订阅
salesOffices.trigger('squareMeter88',200000);


添加中介,发布-订阅用一个全局的Event对象来实现,订阅者不需要了解信息来自哪个发布者,发布者也不知道消息会推送给哪些订阅者,Event作为一个类似“中介者”的角色,把订阅者和发布者联系起来。

var Event=(function(){
var clientList={},
listen,
trigger,
remove;
listen=function(key,fn){
if(!clientList[key]){
clientList[key]=[];
}
clientList[key].push(fn);
};
trigger=function(){
var key=Array.prototype.shift.call(arguments),
fns=clientList[key];
if(!fns||fns.length===0){
return false;
}
for(var i=0,fn;fn=fns[i++];){
fn.apply(this,arguments);
}
};
remove=function(key,fn){
var fns=clientList[key];
if(!fns){
return false;
}
if(!fn){
fns&&(fns.length=0);
} else {
for(var l=fns.length-1;l>=0;l--){
var _fn=fns[l];
if(_fn===fn){
fns.splice(l,1);
}
}
}
};
return {
listen:listen,
trigger:trigger,
remove:remove
}
})();
Event.listen('squareMeter88',function(price){
console.log(price);
});
Event.trigger('squareMeter88',2000000)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息