JavaScript 发布订阅者模式和观察者模式及区别

一、发布订阅模式

发布订阅模式其实是一种对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到状态改变的通知。

多方订阅,一方发布,订阅放会收到通知

举例:教学楼中每个教室都有一个广播器,例如甲同学进入了A教室,甲同学可以理解为订阅,A教室有着A教室的订阅者,当校长只对A教室的广播进行播放时,只有A教室的所有学生可以受到广播信息。

常见的发布订阅比如 Vue中eventBus的 $on - $emit  

js实现一个发布订阅

<script>
  // 发布订阅模式是一种对象间一对多的关系,当一个对象发生改变时,所有依赖于它的对象都能接收到状态的通知

  // 定义eventBus
  class eventBus {
    // 存放所有订阅者的对象
    clientList = {};

    // 发布  (事件名称,参数)
    $emit = function (event, params) {
      // 循环调用订阅的所有callback
      this.clientList[event].forEach((callback) => callback(params));
    };

    // 订阅  (事件名称,回调)
    $on = function (event, callback) {
      // 如果之前键不存在  ?  {updata:[()=>{}]}  : {updata:[()=>{},()=>{}]}
      !this.clientList[event]
        ? (this.clientList[event] = [callback])
        : this.clientList[event].push(callback);
    };
  }

  
  // 创建eventBus实例对象
  const events = new eventBus();

  // 定于 updata的事件名称
  events.$on("updata", (params) => {
    console.log("updata1", params);
  });

  // 定于 updata的事件名称
  events.$on("updata", (params) => {
    console.log("updata2", params);
  });

  // 发布订阅
  events.$emit("updata", "参数");
</script>

我们发现每次进行订阅、通知都是在使用events中的 clientList, 并不会直接用$on 和 $emit 发生关系。

二、观察者模式

观察者模式既一个对象被多个对象所依赖,当依赖的对象发生更新时,会自动通知所有依赖的对象。

观察者模式和发布订阅模式很相似,区别就是 发布订阅者模式会有一个调度中心去互相联系,而观察者模式 只有观察者和被观察者有直系的联系

举例:一家武校,有两位学生,两位学生为观察者,观察着老师的讲话及动作,老师就称为被观察者,老师一有变动,两位学生就能够观察到老师的变动。

  // 定义观察者
    class Teacher {
        constructor (name){
            this.name = name
            // 存储观察者
            this.students = []
        }

        // 添加观察者
        addStu(student){
            this.students.push(student)
        }

        // 删除观察者
        delStu(student){
            const idx =this.students.findIndex(it=>it==student)
            idx!=-1?this.students.splice(idx,1):''
        }

        // 发送通知
        notice(msg){
            console.log(this.name+'老师说:'+msg);
            this.students.forEach(it=>it.updata(msg))
        }
    }

    // 定义被观察者
    class Student {
        constructor(name){
            this.name = name
        }

        updata(msg){
            console.log(this.name+'收到了老师说的:',msg);
        }
    }

    const teacherMa  = new Teacher('马保国')
    const stuJia = new Student('甲')
    const stuYi = new Student('乙')

    teacherMa.addStu(stuJia)
    teacherMa.addStu(stuYi)

    teacherMa.delStu(stuYi)

    teacherMa.notice('我要开始练拳了')

总结

发布订阅者模式和观察者模式都是一对多的关系,每次有新的通知,都会告知订阅者和观察者,最大的区别就是,发布订阅者中有一个调度中心来通知订阅者,而不是像观察者那样 直接通过被(目标)观察者来通知观察者。

猜你喜欢

转载自blog.csdn.net/m0_46846526/article/details/128787037