详解JavaScript中的发布-订阅模式

什么是发布-订阅模式?发布-订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。现实生活中的发布-订阅模式小梁、小花、小红都喜欢上同一家淘宝店铺的同一件衣服,当她们正要下单的之后被店家通知这件衣服没货了。小梁问店家什么时候有货,店家表示得看加工厂的工作进度,具体的上架日期还不确定,但表示可以加入他们家的粉丝群,等到衣服有货了...
摘要由CSDN通过智能技术生成

什么是发布-订阅模式?

发布-订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。

现实生活中的发布-订阅模式

小梁、小花、小红都喜欢上同一家淘宝店铺的同一件衣服,当她们正要下单的之后被店家通知这件衣服没货了。小梁问店家什么时候有货,店家表示得看加工厂的工作进度,具体的上架日期还不确定,但表示可以加入他们家的粉丝群,等到衣服有货了会第一时间通知进群的粉丝。于是小梁、小花、小红都加入该店铺的粉丝群。一周后,店家在粉丝群艾特所有人通知大家衣服重新上架了,小梁、小花、小红第一时间收到了这条消息,高兴地买到了心仪已久的衣服。

发布-订阅模式的作用

  1. 发布-订阅模式可以广泛应用于异步编程中,这是一种替代回调函数的方案。比如,我们可以订阅ajax请求中的success 、error等事件,无需过多关注对象在异步运行期间的内部状态,而只需订阅感兴趣的事件发生点。
  2. 可以取代对象之间硬编码的通知机制,一个对象不再显式地调用另外一个对象的某个接口。当有新的订阅者出现时,发布者的代码不需要任何修改;同样发布者需要改变时,也不会影响到之前的订阅者。只要之前约定的事件名没有变化,就可以自由地改变它们。
  3. 支持简单的广播通信,当对象状态发生改变时,会自动通知已经订阅过的对象。

发布-订阅模式的实现

  1. 确定发布者(店家);
  2. 给发布者添加一个缓存列表,用于存放回调函数来通知订阅者;
  3. 当发布消息时,发布者遍历这个缓存列表,依次触发里面存放的订阅者回调函数。
    另外,还可以往回调函数里填入一些参数,订阅者可以接受到这些参数。
    下面是一个简单的发布-订阅模式:

        //1.指定谁充当发布者(淘宝店家)
        let clothesShop = {
   };

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

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

        //3.发布消息,遍历缓存列表
        clothesShop.trigger = function () {
   
            for(let i = 0,fn;fn = this.clientList[i++];){
   
                fn.apply(this,arguments); //arguments是发布消息时带上的参数
            }
        };

        //测试
        //小梁订阅消息
        clothesShop.listen(function (color,size) {
   
            console.log("颜色是:"+color);
            console.log("尺码是:"+size);
        });
       //小花订阅消息
        clothesShop.listen(function (color,size) {
   
            console.log("颜色是:"+color);
            console.log("尺码是:"+size);
        });

        //发布消息
        //蓝色衣服上架通知所有买家
        clothesShop.trigger("blue","s");
        //粉色衣服上架通知所有买家
        clothesShop.trigger("pink","m");

在这里插入图片描述
虽然这是最简单的发布-订阅模式,但是我们可以发现订阅者接收到了发布者发布的所有消息。其实,小梁只是想买s码的蓝色衣服,小花想买m码的粉色衣服,有没有一种办法可以根据订阅者需要发布订阅者需要的消息呢?

于是我们可以增加一个标示key,让订阅者只订阅自己感兴趣的消息。改写代码如下:

        //1.指定谁充当发布者(淘宝店家)
        let clothesShop = {
   };

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

        //增加订阅者
        clothesShop.listen = function (key,fn) {
   
            if(!this.clientList[key]){
   
                this.clientList[key] = [];  //如果还没有订阅过此条消息,则给该类消息创建一个缓存列表
            }
            this.clientList[key].push(fn);  //订阅的消息添加进消息缓存列表
        };

        //3.发布消息,遍历缓存列表
        clothesShop.trigger = function () {
   
            let key = Array.prototype.shift.call(arguments);  //取出消息类型
            let fns = this.clientList[key];

            if(!fns || fns.length == 0){
       //如果没有订阅该消息,则返回
                return false;
            }

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

        //测试
        //小梁订阅消息
        clothesShop.listen("小梁",function (color,size) {
   
            console.log("这是小梁订阅的:");
            console.log("颜色是:"+color);
            console.log("尺码是:"+size
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值