发布-订阅模式(一)

    发布-订阅模式又被称为观察者模式,它是定义在对象之间一对多的关系中,当一个对象发生变化,其他依赖于它的对象收到通知。在javascript的开发中,我们一般用事件模型替代发布-订阅模式。

DOM事件

 

document.body.addEventListener('click',function(){

    alert(绑定1);

},false)};
document.body.click();  //模拟点击

document.body.addEventListener('click',function(){

    alert(绑定2);

},false)};

document.body.addEventListener('click',function(){

    alert(绑定3);

},false)};


document.body.click();  //模拟点击

我们可以增加更多订阅者,不会对发布者的代码造成影响。注意,标准浏览器下用dispatchEvent实现。

自定义事件

①确定发布者。(例如售票处)

②添加缓存列表,便于通知订阅者。(预订车票列表)

③发布消息。遍历缓存列表。依次触发里面存放的订阅者回调函数(遍历列表,逐个发送短信)。

另外,我们还可以在回调函数填入一些参数,例如车票的价格之类信息。

var ticketOffice = {};    //售票处

ticketOffice.clientList = [];    //缓存列表,存放订阅者的回调函数

ticketOffice.listen = function (fn) {    //增加订阅者
    this.clientList.push(fn);    //订阅的消息添加进缓存列表
};

ticketOffice.trigger = function () {    //发布消息
    for(var i = 0, fn; fn = this.clientList[i++];){
        fn.apply(this, arguments);    //arguments 是发布消息时带上的参数
    }
}

下面进行简单测试:

ticketOffice.listen(function(time, path){    //小刚订阅消息
    console.log('时间:' + time);
    console.log('路线:' + path);
});


ticketOffice.listen(function(time, path){    //小强订阅消息
    console.log('时间:' + time);
    console.log('路线:' + path);
});

ticketOffice.trigger('晚上8:10','深圳-上海');
ticketOffice.trigger('晚上8:10','上海-深圳');

至此,我们实现了一个最简单发布-订阅模式。不过这里存在一些问题,我们运行代码可以看到订阅者接收到了所有发布的消息。我们有必要加个key让订阅者只订阅 自己感兴趣的消息。改写后的代码如下:

var ticketOffice = {};    //售票处

ticketOffice.clientList = [];    //缓存列表,存放订阅者的回调函数

ticketOffice.listen = function (key, fn) {    //增加订阅者
    if (!this.clientList[key]){
        this.clientList[key] = [];
    }
    this.clientList[key].push(fn);    //订阅的消息添加进缓存列表
};

ticketOffice.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);    //arguments 是发布消息时带上的参数
    }
}

ticketOffice.listen('上海-深圳', function(time){    //小刚订阅消息
    console.log('小刚时间:' + time);
});


ticketOffice.listen('深圳-上海', function(time){    //小强订阅消息
    console.log('小强时间:' + time);
});

ticketOffice.trigger('深圳-上海', '晚上8:00');
ticketOffice.trigger('上海-深圳', '晚上8:10');

这样子,订阅者就可以只订阅自己感兴趣的事件了。

 

参考资料:《JavaScript 设计模式与开发实践》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值