1. 程式人生 > >publish/subscribe(發布/訂閱)模式

publish/subscribe(發布/訂閱)模式

事件 互調 有意思 this 標識符 ken con strong scrip

這幾天看《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‘); ~~~~匿名函數的使用,也是很有意思的 《JavaScript設計模式》之 publish/subscribe(發布/訂閱)模式

publish/subscribe(發布/訂閱)模式