維基百科:
觀察者模式是軟件設計模式的一種。在此種模式中,一個目標對象管理所有相依于它的觀察者對象,并且在它本身的狀態改變時主動發出通知。這通常透過呼叫各觀察者所提供的方法來實現。此種模式通常被用來實時事件處理系統。
<基于mvc的JavaScript的富應用開發>上給的解釋:
發布/訂閱模式(Pub/Sub)是一種消息模式,它有兩個參與者: :發布者和訂閱者。發布者向 某個信道發布一條消息,訂閱者綁定這個信道,當有消息發布至信道時就會 接收到一個通知。重要的一點是,發布者和訂閱者是完全解耦的,彼此并不知曉對方 的存在。兩者僅僅共享一個信道名稱。
理解起來很簡單: 我去書報亭訂了一份報紙,當他把報紙送給我了,我就去領了看.
這里,我就變成了訂閱者,報亭就是發布者,當報紙送到的時候(狀態發生改變,通知訂閱者),我就去領了看(做一些操作)
一個發布者應該有三個主要的方法: 訂閱,發布,退訂.
var PubSub = {};
var eventObj = {};
PubSub.subscribe = function(event, fn) {
eventObj[event] = fn;
}
PubSub.publish = function(event) {
if (eventObj[event])
eventObj[event]();
}
PubSub.off = function(event, fn) {
if (eventObj[event])
eventObj[event] = null;
}
var PubSub = (function() {
var eventObj = {};
return {
subscribe: function(event, fn) {
eventObj[event] = fn;
},
publish: function(event) {
if (eventObj[event]) eventObj[event]();
},
off: function(event) {
if (eventObj[event]) delete eventObj[event];
}
}
}());
PubSub.subscribe('event', function() {
console.log('event release');
});
PubSub.publish('event'); // 'event release'
OK it work!!
這絕對是簡單無腦的觀察者模式的實現了,你以為這就完了嗎?
這樣..這個一個事件只能綁定一個操作,并且取消訂閱把整個事件都刪除掉了,這樣就不是很好了,我們應該寫一個支持一個事件綁定多個操作的,并且退訂時是退訂一個事件上的一個操作,而不是刪除整個事件
一個事件綁定多個操作,我們應該用一個數組把操作保存起來,發布時按訂閱順序執行,退訂時刪除對應的數組元素就好.
var PubSub = (function() {
var queue = {};
var subscribe = function(event, fn) {
if (!queue[event]) queue[event] = [];
queue[event].push(fn);
}
var publish = function(event) {
var eventQueue = queue[event],
len = eventQueue.length;
if (eventQueue) {
eventQueue.forEach(function(item, index) {
item();
});
}
}
var off = function(event, fn) {
var eventQueue = queue[event];
if (eventQueue) {
queue[event] = eventQueue.filter(function(item) {
return item !== fn;
});
}
}
return {
subscribe: on,
publish: emit,
off: off
}
}());
以上就是一個簡單的觀察者模式的實現了.
下面來測試一下:
function first() {
console.log('event a publish first');
}
PubSub.subscribe('a', first);
PubSub.subscribe('a', function() {
console.log('event a publish second');
});
PubSub.publish('a'); // event a emit first, event a emit second
PubSub.off('a', first);
PubSub.publish('a'); //event a emit second
本站文章版權歸原作者及原出處所有 。內容為作者個人觀點, 并不代表本站贊同其觀點和對其真實性負責,本站只提供參考并不構成任何投資及應用建議。本站是一個個人學習交流的平臺,網站上部分文章為轉載,并不用于任何商業目的,我們已經盡可能的對作者和來源進行了通告,但是能力有限或疏忽,造成漏登,請及時聯系我們,我們將根據著作權人的要求,立即更正或者刪除有關內容。本站擁有對此聲明的最終解釋權。