Javascript項目中使用 - 訂閱發佈模式

原文連接跳轉javascript

好長時間沒有寫文章了,恰好年末了,就把前段時間在項目中用到和學到的技術方案寫下來,一個是發佈訂閱模式,還有一個就是隊列在項目中的應用了,關於隊列在下一篇文章。html

以前也有了解過發佈訂閱,但在項目中實際使用也是第一次,這個項目重構,小組大佬引入了這個方案!!此次也算是學習到了,如何把一些概念引用到項目中,合理解決軟件項目的實際問題。[如下內容參考:javascript設計模式與開發實踐]()前端

常見的訂閱發佈

在咱們的平常生活中,就能夠找到訂閱發佈,例如咱們在B站中經常使用的的訂閱服務,你在上面訂閱了一個up主,當up主更新了視頻以後,你就會收到對應的通知。固然,這個通知的形式是有各類各樣的,這個就是咱們這裏要討論的。訂閱者 ——> 更新數據 ——> 發佈者通知,這樣的一個流程,就是最最在生活中一個常見的例子了。 java

那在前端項目中,咱們是否有用到發佈訂閱嘛?設計模式

document.addEventListener('click', ()=> {console.log('一號監聽器')})

document.addEventListener('click', ()=> {console.log('二號監聽器')})

以上代碼對點擊事件進行了兩次監聽,它們互相不會覆蓋,這也是在前端項目中,最多見的一個例子🌰。從這個代碼中,咱們能夠發現,addEventListener的做用就是訂閱(監聽),但這裏有兩個監聽,說明進行屢次監聽時,即便監聽的都是click類型的事件,但也不會被覆蓋,說明有一個列表,幫咱們把監聽都進行了保存,而後再同時觸發。好的,咱們也依據咱們分析的,來編寫一個簡易的訂閱發佈器(監聽發佈器)。緩存

實現簡易的訂閱發佈

首先須要一個訂閱器(監聽器),而後須要一個列表進行緩存,最後須要通知觸發(發佈):函數

// 緩存
let _cache = {};

// 監聽器(訂閱)
function addLister(type, fn) {
    if(!_cache[type]) {
        // 類型不存在,就是建立一個緩存列表
        _cache[type] = [];
    }
    // 回調放入緩存
    _cache[type].push(fn);
}

// 觸發器(發佈)
function trigger(type, option = {}) {
    if(!_cache[type]) {
        // 類型不存在,直接結束
        return false;
    }
    let list = _cache[type];
    for(let i = 0 ; i < list.length ; i++) {
        // 遍歷緩存列表,發佈消息通知
        list[i](option);
    }
}

// 訂閱
addLister("click", (e)=> {console.log(e.a);});
addLister("click", (e)=> {console.log(e.b);});
// 發佈
trigger("click", {a: 1, b: 2})

好啦,一個簡易的訂閱發佈器就能夠啦!能夠試試這一段代碼,是否是已經能夠直接使用了,滿滿的成就感。通常在訂閱發佈器都是掛載在全局下的,那麼咱們只須要把以上的函數封裝成一個函數或者一個類就能夠啦!!學習

是否是感受以上的代碼少了一點什麼?訂閱和發佈都有了,若是咱們想取消訂閱怎麼辦,這裏我不繼續說了,但願你本身能夠去翻書或者查資料,別人給的畢竟不如本身作的,取消訂閱的具體實現,留待你們思考吧。至於如何在項目中使用,這個基本也不用說,由於在你的平常項目中,你就有在用哦!![建議直接看:javascript設計模式與開發實踐]()編碼

使用場景和解決的問題

下面要說到的,就是訂閱發佈的使用場景,和解決的問題。固然,其實這能夠概括爲一個問題。設計

這裏我列舉幾個使用的場景:

1. 跨模塊或跨組件的通訊
2. 全局的消息通知
......等

更多的場景想不出來了。。。。。,但願有人能夠補充。我也是看書總結的,就不復制粘貼了,訂閱發佈模式的做用有兩點:

1.解耦; 
2.避免硬編碼;

解藕:避免項目不一樣的模塊和組件的代碼複雜度,多個模塊的代碼交織在一塊兒;避免硬編碼:不須要經過變量手動來強制修改一些狀態;

對於設計模式,重要的是理解其思想,而後嘗試是否能夠運用到項目中去,由於只有使用的知識,纔是活知識嘛。好了,我繼續去看書了。

相關文章
相關標籤/搜索