发布订阅
- 订阅发布模式定义了一种一对多的依赖关系,让多个订阅者对象同时监听某一个主题对象。这个主题对象在自身状态变化时,会通知所有订阅者对象,使它们能够自动更新自己的状态。
- 首先要想好谁是发布者(比如上面的卖家)。
- 然后给发布者添加一个缓存列表,用于存放回调函数来通知订阅者(比如上面的买家收藏了卖家的店铺,卖家通过收藏了该店铺的一个列表名单)。
- 最后就是发布消息,发布者遍历这个缓存列表,依次触发里面存放的订阅者回调函数。
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);//从原数组中去掉第一位,并且返回
var fns=this.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=this.clientlist[key];
if(!fns){
//如果key对应的消息没有被订阅,直接返回
return false;
}
if(!fn){
//如果没有传入具体对应的回调函数,表示取消key对应消息的所有订阅
fns=[]
}else{
for(let index=0;index<fns.length;index++){
var _fn=fns[index];
if(_fn==fn){
fns.splice(index,1)
}
}
}
}
}
var installEvent=function(obj){
for(var i in event){
obj[i] = event[i];
}
}
var saleOffices = {};
installEvent( saleOffices );
saleOffices.listen( "squareMeter88", fn1 = function( price ){
console.log( "价格" + price );
} );
saleOffices.listen( "squareMeter88", function( price ){
console.log( "价格" + price );
} );
saleOffices.remove( "squareMeter88", fn1 );
saleOffices.trigger( "squareMeter88", 200000 );
---------------------
作者:夏岭
来源:CSDN
原文:https://blog.csdn.net/hi_xiexialing/article/details/54645242
版权声明:本文为博主原创文章,转载请附上博文链接!
var event = {
list: [],
listen: function(key,fn) {
if(!this.list[key]) {
this.list[key] = [];
}
// 订阅的消息添加到缓存列表中
this.list[key].push(fn);
},
trigger: function(){
var key = Array.prototype.shift.call(arguments);
var fns = this.list[key];
// 如果没有订阅过该消息的话,则返回
if(!fns || fns.length === 0) {
return;
}
for(var i = 0,fn; fn = fns[i++];) {
fn.apply(this,arguments);
}
},
remove:function(key,fn){
var fns=this.list[key];
if(!fns){
//对应key事情没有被订阅
return false;
}
if(!fn){
//如果没有对应没有传入的函数,则表示全部清空
fns=[];
}else{
for(var i=0;i<fns.length;i++){
if(fns[i]==fn){
fns.splice(i,1);
}
}
}
},
once:function(key,fn){
function one(){
fn.apply(this,arguments);
this.remove(key,one);
}
this.listen(key,one);
}
};
var initEvent = function(obj) {
for(var i in event) {
obj[i] = event[i];
}
};
// 我们再来测试下,我们还是给shoeObj这个对象添加发布-订阅功能;
var shoeObj = {};
initEvent(shoeObj);
// 小红订阅如下消息
shoeObj.once('red',fn1=function(size){
console.log("尺码是:"+size);
});
shoeObj.listen('red',fn1=function(size){
console.log("尺码dierci");
});
// 小花订阅如下消息
shoeObj.listen('block',fn2=function(size){
console.log("再次打印尺码是:"+size);
});
shoeObj.remove("block",fn2);
shoeObj.trigger("red",40);
shoeObj.trigger("block",42);
发布订阅,观察区别
-
区别
-
在观察者模式中,观察者是知道Subject的,Subject一直保持对观察者进行记录。
-
然而,在发布订阅模式中,发布者和订阅者不知道对方的存在。它们只有通过调度中心进行通信。
-
在发布订阅模式中,组件是松散耦合的,正好和观察者模式相反。
-
观察者模式大多数时候是同步的,比如当事件触发,Subject就会去调用观察者的方法。而发布-订阅模式大多数时候是异步的(使用消息队列)
-
而发布订阅模式中统一由调度中心进行处理,订阅者和发布者互不干扰。这样一方面实现了解耦,还有就是可以实现更细粒度的一些控制。比如发布者发布了很多消息,但是不想所有的订阅者都接收到,就可以在调度中心做一些处理,类似于权限控制之类的。还可以做一些节流操作
-
观察者模式中观察者和目标直接进行交互
网友评论