发布订阅模式
Jonnzer Lv4

本文摘自《Javascript设计模式与开发实践》

1. 定义

  • 对象之间的依赖关系。当一个对象的状态发生改变时,所有依赖它的对象都会得到通知
  • Javascript一般用事件模型来替代传统的发布-订阅模式
  • 可能会有中介这个身份,中转所有依赖关系。让发布者和订阅者不需要了解彼此。

2. 优点

  • 提供数据方,和接受数据方,不是强耦合的关系

3. 模拟

1
2
3
4
document.body.addEventListener('click', () => {
alert(2)
}, false)

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// 中间者统一处理
var Event = (function() {
var clientList = {},
listen,
trigger,
remove;

listen = function (key, fn) { // 添加
if (!clientList[key]) {
clientList[key] = []
}
clientList[key] = fn
}

trigger = function () { // 通知、发布
var key = Array.prototype.shift.call(arguments),
fns = clientList[key];
if (!fns || fns.length === 0) {
return false;
}
for (var i = 0,fn; fn = fns[i++]) {
fn.apply(this, arguments)
}
}

remove = function (key, fn) { // 删除
var fns = clientList[key]
if (!fns) {
return false
}
if (!fn) { // 如果没有传入具体的回调函数,表示需要取消 key 对应消息的所有订阅
fns && (fns.length = 0)
} else {
for (var i = fns.length -1; i>=0; i-- ) {
var _fn = fns[i]
if (_fn === fn) {
fns.splice(i, 1)
}
}
}
}

return {
listen: listen,
trigger: trigger,
remove: remove
}
})

// 小红订阅消息 // 输出:'价格=2000000'
Event.listen( 'squareMeter88', function( price ){
console.log( '价格= ' + price )
});

Event.trigger( 'squareMeter88', 2000000 );// 售楼处发布消息

4. 思考🤔

订阅发布的顺序:
原本是先订阅,再发布,因为先发布没订阅的情况下,消息会丢失
增加先发布后订阅的能力:离线事件的堆栈,用来存储尚未被订阅的离线事件。等到有订阅的时候,再遍历堆栈执行。
需要注意的是,离线事件的触发只有一次。(具体代码实现结合书本参考 )

5. 优缺点

+ 优点:时间和对象上的解耦,常用于异步编程。
+ 缺点:订阅了消息,订阅者会始终存在内存中。对象之间的必要联系会难以跟踪。

参考

设计模式篇观察订阅模式第10节
apply

  • 本文标题:发布订阅模式
  • 本文作者:Jonnzer
  • 创建时间:2021-03-18 21:16:25
  • 本文链接:https://jonnzer.github.io/2021/03/18/设计模式-发布订阅/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
 评论