Q:何为发布订阅模式?
A:这是一种发布者和订阅者之间由事件驱动产生关系的软件开发模式
Q:发布订阅模式哪里可以看到?
A:可能你没意识到,也许你接触的最早的发布订阅就是DOM事件
/*
click是订阅的事件
匿名函数function事件发布之后的反馈动作
*/
document.body.addEventListener( 'click', function(){
alert(2);
}, false ); //订阅
document.body.click(); //click事件发布,当然用户点击页面主体也能也能触发发布
-------------分割线开始构思我自己的发布订阅模式-------------
一、我的发布订阅器取个名字EventPublicher
二、订阅部分
1.需要一个变量,存储所有订阅类型
2.需要一个订阅方法,用来存储订阅类型,一种订阅可能被订阅多次
3.订阅方法本身要有方法回调,便于对事件发布做反馈
var EventPublicher = {
list : {},
listen : function(type, fn){ //订阅方法type:类型 fn订阅回调事件
!this.list[type] && (this.list[type] = []); //订阅的类型池子初始化
this.list[type].push(fn); //塞入回调方法
}
};
//加一条试试看
EventPublicher.listen("test", function(){});
EventPublicher.list;
三、发布部分
1.需要一个发布方法,接受类型参数,触发订阅类型下相关的回调方法
var EventPublicher = {
list : {},
listen : function(type, fn){ //订阅方法 type:类型 fn订阅回调事件
!this.list[type] && (this.list[type] = []); //订阅的类型池子初始化
this.list[type].push(fn); //塞入回调方法
},
fire : function(type){ //发布方法 type:类型
if(this.list[type]){ //如果有这种类型的订阅
var lists = this.list[type];
for(var i = 0; i < lists.length; i++){
if(typeof lists[i] == 'function'){ //排除订阅的没存入回调方法
lists[i](); //调用订阅回调
}else{
console.log("订阅类型:"+type+"传入的回调不是function");
}
}
}else{
console.log("没有找到订阅类型:"+type);
}
return this;
}
};
//发布一次试试看
EventPublicher.listen("test1",function(){
console.log("你发布了:test1");
});
EventPublicher.fire("test1");
四、我想一次性添加多个订阅或者多个发布
var EventPublicher = {
list : {},
listen : function(type, fn){ //订阅方法 type:类型 fn订阅回调事件
!this.list[type] && (this.list[type] = []); //订阅的类型池子初始化
this.list[type].push(fn); //塞入回调方法
return this; //链式调用的关键
},
fire : function(type){ //发布方法 type:类型
if(this.list[type]){ //如果有这种类型的订阅
var lists = this.list[type];
for(var i = 0; i < lists.length; i++){
if(typeof lists[i] == 'function'){ //排除订阅的没存入回调方法
lists[i](); //调用订阅回调
}else{
console.log("订阅类型:"+type+"传入的回调不是function");
}
}
}else{
console.log("没有找到订阅类型:"+type);
}
return this;//链式调用的关键
}
};
//发布一次试试看
EventPublicher.listen("test1",function(){
console.log("你发布了:test1");
}).listen("test2",function(){
console.log("你发布了:test2");
});
EventPublicher.fire("test1").fire("test2");
五、我想给发布订阅器独特的识别名称,并且我想要给订阅回调传一些独特的参数
//我是售楼处的,我想通知我的客户新房源信息
var EventPublicher = {
list : {},
listen : function(type, fn){ //订阅方法 type:类型 fn订阅回调事件
!this.list[type] && (this.list[type] = []); //订阅的类型池子初始化
this.list[type].push(fn); //塞入回调方法
return this; //链式调用的关键
},
fire : function(type, args){ //发布方法 type:类型
if(this.list[type]){ //如果有这种类型的订阅
var lists = this.list[type];
for(var i = 0; i < lists.length; i++){
if(typeof lists[i] == 'function'){ //排除订阅的没存入回调方法
lists[i](args); //调用订阅回调
}else{
console.log("订阅类型:"+type+"传入的回调不是function");
}
}
}else{
console.log("没有找到订阅类型:"+type);
}
return this;//链式调用的关键
},
copy : function(obj){
for(var key in EventPublicher){
if(key != 'copy'){
obj[key] = EventPublicher[key];
}
}
}
};
//发布一次试试看
var Lianjia = {};
EventPublicher.copy(Lianjia);
Lianjia.listen("squar88", function(args){
console.log("李先生88平米的房子,有新货源了,现在价格是:"+args.price);
});
Lianjia.listen("squar88", function(args){
console.log("于先生88平米的房子,有新货源了,现在价格是:"+args.price);
});
Lianjia.fire("squar88",{"price" : "180万"});
网友评论