订阅发布设计模式
最近在看
react
的时候发现比较有意思的事情。
react 的组件通信是一个比较常见的问题,大致分为以下几种:
- 父->子通信:传入 props 解决
- 子->父通信:父组件传入一个函数给子组件,通过子组件调用触发,拿到值;或者用 HOC
- 跨越层级比较多的通信:通过 Context 传值
- 兄弟之间的通信:
- 放在一个父节点下,通过 props 传值,或者函数传值
- 哥俩都通过 HOC 包装起来传值
- 直接用 Context 传值
- 把数据放在第三方(或者全局,比如 Redux),统一通过第三方来获取数据
- 通过发布订阅的方式传值,本篇主要记这个。
发布订阅设计模式一般分为三个部分:
- 发布者:就是喊话的人(一般就几个人,比较少)
- 订阅者:就是听者(可能一两个,可能很多人)
- 通道:就是传声渠道(比如空气,电话)
这个模式在生活中也比较常见:
- 在油管上订阅自己喜欢的 Youtuber,看 Youtuber 发布的视频。
- 以前家里人都喜欢看湖南卫视,到了黄金时间都锁定湖南卫视看热播剧场。
- 推特关注自己喜欢的偶像、体育赛事,新闻时事,有信息第一时间知道。
其中,上述的关注对象一般是发布者,关注人一般是订阅者,其中的”油管“,”湖南卫视“,”推特“一般是渠道。了解了大致的原理,我们可以手写一个发布订阅的小玩意加深印象。
首先,我们需要一个对象来存储订阅关系,并且需要这是一个单列的,因为不能简单的让外部进行改动。
1 | class SubPub { |
然后,实现我们的订阅功能。
1 | static subscribe(message: string, fn: Function) { |
上面我们为了更方便操作函数,给函数加上了唯一索引,所以我们需要在类的定义里加上索引定义,同样也是单列。
1 | private static lastUid: number = 0; |
上面已经实现了订阅了,我们来实现发布功能。
1 | static publish(message: string, data?: any) { |
现在我们就可以去使用了。
1 | let myUid = NaN; |
有了订阅,应该也有取消的功能,因为很多业务是只能登陆用户才能办理的,或者说业务有时效性的。
下面我们来实现取消的功能。
1 | static unsubscribe(message: string, uid: number) { |
用起来也很方便。
1 | SubPub.unsubscribe("lucky", myUid); |
不方便的地方就是存储唯一索引麻烦些。
好了,本篇的大致内容差不多就是这些了,以上只是简单的书写,我们只要了解核心原理就行了,如果你想要看更深入的话,访问PubSubJS
的github
。
enjoy and happy coding!