龙空技术网

带你轻松搞定“观察者模式“和"发布订阅模式"的区别

知了堂 106

前言:

今天同学们对“发布订阅者模式和观察者模式的区别”可能比较珍视,小伙伴们都想要分析一些“发布订阅者模式和观察者模式的区别”的相关内容。那么小编同时在网摘上汇集了一些有关“发布订阅者模式和观察者模式的区别””的相关内容,希望你们能喜欢,看官们一起来学习一下吧!

模式的概念

最近我的小伙伴们在面试中,这两个被问的很频繁,斗胆的跟大家分享一下我的理解。我将采用“官方解释”+“大白话”的方式。

熟悉Vue的小伙伴都知道,在Vue中使用“观察者模式”去通知视图更新,使用“发布订阅”$on,$emit来实现自定义事件,所以搞清楚两者之间的关系很重要啦!

观察者模式:一个对象(观察者)订阅另一个对象(主题),当主题被激活的时候,触发观察者里面的事件。

大白话解释:当去你去医院打吊瓶(某些地方叫打点滴,就是这么严谨)的时候,医生要观察吊瓶的改变,当快打完的时候,就要通知医生来取针。这里医生就是观察者(Obeserver),吊瓶就是被观察者/主题。

     class Subject { //被观察者数据---吊瓶           constructor(name="知了哥"){               this.state = 100;               this.name = name;               this.obs = [] //会有多个观察者           }          addObs(ob){               this.obs.push(ob)          }          setState(state){ //改变状态的方法              this.state = state              //要去通知观察者去做动作,--- 拔针               this.obs.forEach((ob)=>{                   ob.update(this) //让观察者去做更新              })          }     }     class Obeserver{ //观察者 -- 医生                  constructor(name){             this.name = name;             //在观察者里面是不是也可以记录 观察了哪些 数据(吊瓶)         }         update(subject){               //医生也有可能观察多个 打针的人                if (!subject.state) {                     console.log(`${this.name} 收到通知 :${subject.name} 的 带瓶打完啦!`)               }else {                    console.log(` ${this.name} 收到通知 :${subject.name} 的 带瓶量: ${subject.state}!`)               }                 }     }     var zhiliao = new Subject();     var hushi = new Obeserver("护士");     var yisheng = new Obeserver("医生")     zhiliao.addObs(hushi) //把观察者放到被观察这的里面去     zhiliao.addObs(yisheng)     zhiliao.setState(50) 复制代码
发布订阅:订阅者把自己想要订阅的事件注册到调度中心,当发布者发布事件到调度中心(就是该事件被触发),再由调度中心统一调度订阅者注册到调度中心的处理代码。

大白话解释:其实简单理解就是我们的自定义事件,比如在Vue中,Vue实例($bus)就是统一的调用中心,我们使用$bus去$on一个自定义事件myEvent就是发布者发布一个事件到调度中心,然后在其他地方$bus.$emit(myEvent)一下就相当于事件被触发,然后$bus就去执行对应事件的回调函数 。哈哈,好绕口!再比如毛十八去邮局里面订阅报纸,订阅了南方都市报,那南方都市报就是我们的发布者,当发布新报纸的时候,邮局再去通知所有的订阅者取报纸啊!

    var Event = {    _listeners: {},        // 添加    $on: function(type, fn) {        if (typeof this._listeners[type] === "undefined") {            this._listeners[type] = [];        }        if (typeof fn === "function") {            this._listeners[type].push(fn);        }            return this;    },    // 触发    $emit: function(type) {        var arrayEvent = this._listeners[type];        if (arrayEvent instanceof Array) {            for (var i=0, length=arrayEvent.length; i<length; i+=1) {                if (typeof arrayEvent[i] === "function") {                    arrayEvent[i]({ type: type });                    }            }        }            return this;    },    // 删除    $off: function(type, fn) {        var arrayEvent = this._listeners[type];        if (typeof type === "string" && arrayEvent instanceof Array) {            if (typeof fn === "function") {                for (var i=0, length=arrayEvent.length; i<length; i+=1){                    if (arrayEvent[i] === fn){                        this._listeners[type].splice(i, 1);                        break;                    }                }            } else {                delete this._listeners[type];            }        }        return this;    }};       复制代码

总结:学习这两种模式,其实就是为了 代码解耦 ,让每个独立的对象分开。小伙伴需要从日常的业务场景去观察,比如在分页插件中,就可以利用“发布订阅”为点击每一个分页数的时候触发($emit)一个自定义事件,如果需要在点击分页的是做一些其他的时候,就可以在外面$on 这个事件,那么分页插件就可以很好的封装起来,不用给里面传递参数或者回调函数之类的了。

《前端每日一题》之闭包问题

《前端每日一题》之this和闭包

《前端每日一题》之this和arguments

标签: #发布订阅者模式和观察者模式的区别 #发布订阅者模式和观察者模式 #发布订阅 观察者模式