美文网首页
订阅发布模式

订阅发布模式

作者: Eason_0cce | 来源:发表于2019-08-05 14:38 被阅读0次

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万"});

相关文章

网友评论

      本文标题:订阅发布模式

      本文链接:https://www.haomeiwen.com/subject/wfrmdctx.html