觀察者模式建立自定義事件

2022-06-23 04:27:12 字數 1908 閱讀 9176

觀察者模式又稱發布-訂閱模式,主要做「訂閱」、「發布」、「撤銷訂閱」三種操作,事件處理系統就是這種模式的乙個實現。

被觀察者定義乙個快取,儲存訂閱者的處理函式。當有新的訊息發布,被觀察會去檢索快取看有沒有觀察者訂閱這個訊息,有的話呼叫對應的處理函式。

觀察者模式使得觀察者和被觀察者相互分離,避免了相互呼叫的緊耦合狀態。從效果上看,實現相同的目的,觀察者模式可以避免過多的條件分支,同時訂閱發布的頻率難以影響**的複雜度。

首先定義乙個觀察者模式物件(observer),觀察者有「發布」、「訂閱」、「撤銷」三種操作以及乙個儲存訂閱處理函式的快取。快取儲存型別與**函式的最終結構如下:

整個物件定義如下:

var observer =,

fire :

function(type, msg){},//

發布函式,傳遞發布型別以及相應訊息

on : function(type, callback){},//

訂閱函式,傳遞訂閱型別與處理函式

un : function(type, callback){}//

解訂函式,傳遞要取消某型別及某處理函式

};

再看發布函式。發布函式做的事是找到快取池裡對應型別的所有處理函式,然後依次執行一遍這些處理函式。

observer.fire = function

(type, msg)

};

接著看訂閱函式。訂閱函式做的事是把訂閱的型別與**函式儲存進_cachepool中。先判斷快取中有該型別的空間沒,沒有的話建立該型別空間再儲存**函式,有的話直接儲存。

observer.on = function

(type, callback)

this

._cachepool[type].push(callback);

};

最後看解除訂閱。它做的事是把快取池中相應型別的**函式刪除。

observer.un = function

(type, callback) );

}};

解訂函式刪除相應**函式用到array.prototype.filter函式,這個函式屬於ecma 5新增內容。古董瀏覽器沒有這個函式,我們可以自己寫乙個相容的filter:

var filter = function

(arr, callback)

}return

resultarr;

}

當然,我們可以擴充套件array:array.prototype.filter = array.prototype.filter || filter;這樣就不用調整解訂函式filter的用法了。

觀察者模式測試如下:

observer.on('click', onclick);

observer.on('click', function(msg) );

observer.on('click', onclick);

observer.fire('click', "hello world!");

observer.un('click', onclick);

console.log("解訂後:");

observer.fire('click', "hello world!");

//結果:

click..hello world!click...拉姆達 hello world!click..hello world!解訂後:

click...拉姆達 hello world!

簡易自定義事件達成!

當然,你可以用原生事件處理你新定義的事件,只要實現訂閱好事件,然後在原生事件裡發布該事件的訊息即可。後面的簡易富文字編輯器(二)中會具體實踐。

觀察者模式(自定義事件)

npm install pubsub js舉例如下 import node modules pubsub js src pubsub.js var target when target change 事件的名字 var targetchange targetchange 告訴所有觀察者 事件targ...

自定義事件觀察者及擴充套件

事件觀察者又可以叫事件委託 訂閱模式,目的是為了解偶,定義了一種一對多的關係,當事件變化時通知與此事件依賴的物件,並做出相應的處理。應用時非常廣的,我在做遊戲中時必定用到的,是最最基礎的模組,資料更新 玩家動作觸發 幀頻重新整理 伺服器訊息響應 介面與邏輯分離 狀態變遷等等。我在理解觀察者模式的基礎...

自定義註冊內容觀察者

當我們的某個資料庫或者陣列列表等發生新增,刪除等改變時,我們希望能在 中立馬知道,那麼這時候可以使用內容觀察者。先在想觀察的方法裡註冊觀察者 public void add string packagename public void delete string packagename db.clo...