事件觀察者又可以叫事件委託、訂閱模式,目的是為了解偶,定義了一種一對多的關係,當事件變化時通知與此事件依賴的物件,並做出相應的處理。應用時非常廣的,我在做遊戲中時必定用到的,是最最基礎的模組,資料更新、玩家動作觸發、幀頻重新整理、伺服器訊息響應、介面與邏輯分離、狀態變遷等等。我在理解觀察者模式的基礎上作出了一些改動,使用起來會更方便與快捷。
首先,事件觀察者監聽事件,然後當收到事件觸發時,呼叫事件響應函式,完成一次事件的變遷。
那麼,事件觀察者內部會存在乙個事件列表來維護事件繫結,即為 eventmap ,其中key是唯一值是事件id,通過區分事件id來劃分事件監聽函式。
乙個事件id對應多個響應事件
事件id不可重複
同乙個事件id的事件響應函式不可重複。
事件列表中的每乙個元素可以包涵4個元素,我使用typescript
實現整個類。
eventid 事件id
callback 事件響應函式
thisobj 作用域指標
once 是否觸發一次
export class eventdispatcher ;
return instance;}}
}on 函式只要不移除事件,只要事件觸發就會響應。
once 函式只監聽一次事件,事件觸發一次後就會移除。
public on(eventid: any, callback: function, thisobj?: any): eventdispatcher
public once(eventid: any, callback: function, thisobj?: any): eventdispatcher
public has(eventid: any, callback: function, thisobj?: any): boolean
private addeventlistener(eventid: any, callback: function, thisobj: any, once: boolean = false): void
list.push();
}private haseventlistener(eventid: any, callback: function, thisobj: any): boolean
}return false;
}
off 函式接受 事件id、響應函式、作用域,根據這三個引數來確定移除哪個響應
offall 函式接受 事件id 時移除指定事件id的所有響應函式列表,如果不傳值,則刪除所有的響應函式。
offtarget 函式接受物件指標,通過物件刪除所有監聽
public off(eventid: any, callback: function, thisobj?: any): eventdispatcher
public offall(eventid?: any): eventdispatcher
else ;
}return this;
}public offtarget(target: any): eventdispatcher
private removeeventlistener(eventid: any, callback: function, thisobj: any): void
}}private removeeventlistenerbytarget(thisobj: any): void , this);}}
emit 函式接受事件id、傳遞引數資料。
通過迴圈遍歷依次響應事件列表,如果是once則響應後直接刪除。
emit(事件, data);
public emit(eventid: any, data?: any): eventdispatcher
private dispatchevent(eventid: any, data?: any): void
}
all 函式接受乙個事件id列表,目的是當函式列表內的所有函式都觸發後,才觸發響應函式。
這裡使用了閉包,通過包內作用域,呼叫 once 函式監聽及收集資料並響應函式。
all([ 事件1,事件2,事件3 ], callback, thisobj);
public all(events: any, callback: function, thisobj?: any): eventdispatcher ;
let eventsclone = events.concat();
eventsclone.foreach(function (item) , 0);
}}, null);
}, this);
return this;
}
以上定義的函式滿足事件觀察者的所有特性,也作出了一些寫法上的處理如鏈式呼叫,使**更加優雅。
但是為了功能及便捷,沒有永遠適合的處理,因此我又加上了 plugin 模式,意思就是 eventdispatcher 可以作為另乙個 eventdispatcher 子節點,當父節點的事件觸發時,可以向下繼續處理子節點的事件響應,直到處理完畢。
} //修改後的 dispatchevent 函式
private dispatchevent(eventid: any, data?: any): void
//增加外掛程式的繼續處理
var list = ;
for (var key in this._pluginmap)
list.foreach(function (ed) , this);
} }
}只要子節點監聽了與父節點相同的事件,父節點觸發事件,子節點也會響應。
var ed1 = eventdispatcher.create();
ed1.on('event1',callback1,this);
var ed2 = eventdispatcher.create();
ed2.on('event1',callback2,this);
ed1.plugin(ed2);
ed1.emit('event1');//ed2 同樣會觸發 event1 事件
ed2.emit('event1');//ed1 不會觸發 event1 事件
到此為止,事件觀察者的功能已經挺完善的了,但是需求時在變更的,如果有更好更便捷更有趣的功能,會繼續加上! 觀察者模式(自定義事件)
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...