发布订阅模式
        
        
            本文摘自《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. 优缺点
+ 优点:时间和对象上的解耦,常用于异步编程。
+ 缺点:订阅了消息,订阅者会始终存在内存中。对象之间的必要联系会难以跟踪。
参考
- 本文标题:发布订阅模式
 - 本文作者:Jonnzer
 - 创建时间:2021-03-18 21:16:25
 - 本文链接:https://jonnzer.github.io/2021/03/18/设计模式-发布订阅/
 - 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
 
         评论