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

来源:互联网 发布:刷qq会员软件 编辑:程序博客网 时间:2024/05/15 20:51
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)
原创粉丝点击