美文网首页
订阅发布模式

订阅发布模式

作者: 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