觀察者模式
觀察者模式
????實際上是一個可觀察對象(Observable),內部存在一個對象幻锁,用于收集觀察者(observers),可觀察對象內部存在3個方法,訂閱边臼,發(fā)布哄尔,取消訂閱。也可以理解稱為Publisher/Subscribers模式柠并。
// 首先定義一個可觀察對象
var Observable = function() {
//只有一個用于收集訂閱者的對象,這個地方要寫成公共對象
// 不能用var subscribers = {}, 這樣會寫成私有對象
this.subscribers = {};
} ;
// Observable 對象原型上上的3個方法: subscribe, unsubscribe, publish
Observable.prototype = {
constructor: Observable,
// subscribe @param1 type @param2 fn
subscribe: function(type, fn) {
// 首先查看對象subscribers上是否存在type屬性
if (!this.subscribers[type]) {
this.subscribers[type] = [];
}
// 將訂閱者加入到 subscribers 中
// subscriber is just a function岭接,訂閱者僅僅是一個函數(shù)而已
this.subscribers[type].push(fn);
},
// unsubscribe 取消訂閱 @param1 type @param2 fn
unsubscribe: function(type, fn) {
// 先判斷subscribers中存不存在type這個屬性,不存在直接返回
if (!this.subscribers[type]) {
return;
}
// 存在type,將要取消訂閱的訂閱者找出臼予,從訂閱者名單中刪除掉
var listeners = this.subscribers[type],
i,
len = listeners.length;
for (i = 0; i < len; i++) {
if (listeners[i] === fn) {
// 將取消訂閱的觀察者observer移除
listeners.splice(i, 1);
return;
}
}
},
// publish: 發(fā)布 @param1 type @param2 eventArgs(事件信息)
publish: function(type, event) {
// 判斷觀察者對象集合subscribers中存不存在type屬性鸣戴,不存在則表示為訂閱,直接返回
if (!this.subscribers[type]) {
return;
}
// 先判斷對象event中存不存在type這個屬性粘拾,不存在就創(chuàng)建該屬性
if (!event[type]) {
event[type] = type;
}
// 找到該事件對應的觀察者窄锅,并發(fā)布通知
var listeners = this.subscribers[type],
i,
len = listeners.length;
for (i = 0; i < len; i++) {
listeners[i](event);
}
}
}
示例應用:
// 創(chuàng)建一個可觀察者Observable實例
var publisher = new Observable();
// 創(chuàng)建一個對象傳入到訂閱者中
var eventArgs = {message: "hello observer pattern!"};
// 創(chuàng)建一個訂閱者
var subscriber = function(eventArgs) {
console.log(eventArgs.message);
};
// 訂閱 @param1 type @param2 fn
publisher.subscribe("message", subscriber);
// 發(fā)布 @param1 type @param2 eventArgs(事件信息)
publisher.publish("message", eventArgs); // "hello observer pattern!"
關鍵點:
- 注意發(fā)布者和訂閱者之間的關系是通過發(fā)布者上的一個對象來建立交互的,即subscribers
- 訂閱者本質上是一個函數(shù)(javascript中函數(shù)也是一個對象)
- 訂閱缰雇,取消訂閱入偷,發(fā)布的功能都在發(fā)布者身上,訂閱者只是通過依附(attach)或者脫離(disattach)來訂閱或者退訂事件