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(發布/訂閱)模式


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM