# 发布订阅模式
发布—订阅模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。在JavaScript开发中,我们一般用事件模型来替代传统的发布—订阅模式。
以买房子为例,所有的购房者都是订阅者,当房子开始销售的时候,售楼处群发短信,所有的人都能收到信息。
使用发布—订阅模式有着显而易见的优点:
- 购房者不用再天天给售楼处打电话咨询开售时间,在合适的时间点,售楼处作为发布者会通知这些消息订阅者。
- 购房者和售楼处之间不再强耦合在一起,当有新的购房者出现时,他只需把手机号码留在售楼处,售楼处不关心购房者的任何情况,不管购房者是男是女还是一只猴子。而售楼处的任何变动也不会影响购买者,比如销售离职,售楼处从一楼搬到二楼,这些改变都跟购房者无关,只要售楼处记得发短信这件事情。
发布订阅模式广泛应用于异步编程中,这是一种替代传递回调函数的方案。
const fs = require("fs")
const path = require("path")
// 事件中心
let events = {
_events: [],
on(fn) {
this._events.push(fn)
},
emit(data) {
this._events.forEach((fn) => fn(data))
},
}
events.on(() => {
console.log("每emit一次 就触发一次")
})
let arr = []
events.on((data) => {
console.log("每emit一次 就push一次")
arr.push(data)
})
events.on(() => {
if (arr.length === 2) {
// 最终结果还是计数器
console.log("读取完毕", arr)
}
})
// 订阅有顺序 可以采用数组来控制
fs.readFile(path.resolve(__dirname, "./a.txt"), "UTF8", function (err, data) {
if (!err) {
events.emit(data)
}
})
fs.readFile(path.resolve(__dirname, "./b.txt"), "UTF8", function (err, data) {
if (!err) {
events.emit(data)
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41