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

带你轻松搞定“观察者模式“和”发布订阅模式”的区别模式的概念最近我的小伙伴们在面试中 这两个被问的很频繁 斗胆的跟大家分享一下我的理解 我将采用 官方解释 大白话 的方式

大家好,欢迎来到IT知识分享网。

模式的概念

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

熟悉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

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/184994.html

(0)
上一篇 2025-08-04 09:10
下一篇 2025-08-04 09:15

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信