今天聊聊发布订阅模式。这玩意儿其实挺生活化的——你微信上关注了一堆公众号,哪天这些号更新了,微信就会弹个通知告诉你。说白了,这就是发布订阅的一种简单写照。
关键点在于:发布者和订阅者之间并不直接打交道,而是通过一个调度中心来中转信息。一个事件可以被多个订阅者监听,一个订阅者也能同时关心多个不同的事件。

Vue的响应式系统,本质上就是数据劫持跟发布订阅模式结合后的产物。想真正理解Vue的设计思路,绕不开对这个模式的理解。
整个模式里,有三个核心角色:
- 订阅者:把自己想监听的事件,提前登记到调度中心里。
- 调度中心:当发布者通知有任务时,由它负责唤起所有相关的订阅者(也就是执行他们留下的代码)。
- 发布者:把任务或事件,推送到调度中心。
理论说太多容易晕,直接看代码实现。
复制代码html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<script>
class Publish {
constructor() {
// 调度中心,订阅者把自己要订阅的东西注册到这里
// this.events = {
// event1: [fn1, fn2, fn3]
// event2: [fn1, fn2]
//}
this.events = {}
} // 订阅,订阅者把把事件注册到调度中心
$on(type, fn) {
if (!this.events[type]) {
this.events[type] = []
} this.events[type].push(fn)
} // 发布,通过调度中心发布
$emit(type) {
if (this.events[type]) {
const args = Array.prototype.slice.call(arguments, 1)
this.events[type].forEach(fn => {
fn(...args)
});
}
}
} const eventHub = new Publish() // 订阅:把事件注册到调度中心
eventHub.$on('sum', function() {
const total = [...arguments].reduce((x, y) => x + y)
console.log(total)
}) // 发布:如果有人订阅,那么就执行注册的代码
eventHub.$emit('sum', 1, 2, 3)
script>
body>
html>
发布订阅的实现方式有很多种,上面这段代码展示的,是Vue里比较典型的一种思路。
接下来,再看看观察者模式。
