publish/subscribe(发布/订阅)模式

这几天看《JavaScript设计模式》看的云里雾里的,设计模式看似是具体的东西,却又抓不住。在想发布/订阅模式的形态时,开启新思路,有所收获。
 
 
 化繁为简分析,倒推分析; 化简为繁,是实际项目。
 
实际场景
 
有一个函数,所传参数不同执行结果不同;
另一个函数,所传参数不同执行结果不同... 有很多参数
 
正常情况我们会把代码罗列下来,就像积木一样, 这样看起来整个代码比较杂乱,如果函数之间相互调用会更乱,也不易于维护。
 
有问题就要解决,聪明的前辈们根据现象,思考出从各个维度对代码进行优化,总结出使用频率高的方式方法,也就是设计模式。
 
设计模式其实是一种形式。
 
 
基于上述问题解决方法
 
倒推的方式,先实现后调用
 
 模块功能
 
 定义一个存放函数的对象topics
 把实现不同功能的函数存放到定义的对象里,动态添加对象属性,对象每个属性是存放对应功能函数和其编号
 
*topics= {
      "topic1":[{token:0, fn}],
      "topic2":[{token:1, fn1}],
      "topic3":[{token:2, fn2}],
      "topic3":[{token:3, fn2}]
     }
 
 
 定义一个全局对象,把处理上述添加对应的执行函数,以及根据参数执行功能函数挂载到这个对象上。
 
 
// 定义一个全局对象,挂载处理函数事件
 
let pubsub = {};
 
// 定义一个立即执行的匿名函数,生成独立的作用域, es6中可以使用{}形成独立的作用域,但是不能传参
(function (q) {
    let topicObj = {},
        subUid = -1;
 
 
    // 订阅方法,也是添加函数的方法
    // topic是作为动态的属性名, fn是对应的执行函数
    q.subscribe = (topic, fn) =>{
        // 判断topicObj对象中是否有对应的topic属性,如果没有则设置为数组
        if(!topicObj[topic]){
            topicObj[topic] = []
        }
 
 
        // 下标计算,是属性值,所以要转化为字符串
        let token = (++subUid).toString()
 
 
        // 添加到数组中
        topicObj[topic].push({
            token:token,
            fn:fn
        })
 
 
        //console.log( topicObj )
        //return唯一的标识符token,用于删除指定的项
        return token;
    }
 
 
    // 发布方法,也是执行函数
    q.publish = (topic, args)=> {
        if(!topicObj[topic])return;
 
 
        // 获取指定topic属性项,并获取长度
        let subscribes =  topicObj[topic],
            len = subscribes.length;
 
 
        //console.log(--len);
 
 
        // 遍历并执行
        while (len--){
            // 回调函数有2个参数,一个表示属于对像的属性,另一个则是变量,在定义函数的时候要注意
            subscribes[len].fn(topic, args);
        }
        return this;
    }
 
 
    //  删除订阅者,即对象中指定的属性,也就是对应动态添加的函数
     q.delScribe = (token)=>{
        for(let key in topicObj){
            topicObj[key].forEach((item, i)=>{
                if(item.token===token){
                    topicObj[key].splice(i,1)
                }
            })
        }
         console.log( topicObj )
         return this;
     }
 
})(pubsub);
 
 
//console.log(pubsub);
 
 
//测试
let msg = (data)=>{
    // 这里还可以执行其它相关的函数
    console.log('data---',data);
}
 
 
pubsub.subscribe('test', msg);
pubsub.publish('test', '这是数据');
//pubsub.delScribe('0');
 
~~~~匿名函数的使用,也是很有意思的。 不过是不很眼熟, jQuery框架使用的方式
 
(function(window){
 
jquery=function(){}   // 相关代码
 
window.jquery = jquery;
})(window)
 
《JavaScript设计模式》之 publish/subscribe(发布/订阅)模式
原文地址:https://www.cnblogs.com/wjh0916/p/10840011.html