1、發(fā)布—訂閱模式又叫觀察者模式耙册,它定義對(duì)象間的一種一對(duì)多的依賴關(guān)系给僵,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對(duì)象都將得到通知。在 JavaScript開發(fā)中帝际,我們一般用事件模型來替代傳統(tǒng)的發(fā)布—訂閱模式蔓同。
2、第一點(diǎn)說明發(fā)布—訂閱模式可以廣泛應(yīng)用于異步編程中蹲诀, 這是一種替代傳遞回調(diào)函數(shù)的方案斑粱。或者如果想在動(dòng)畫的每一幀完成之后做一些事情脯爪,那我們可以訂閱一個(gè)事件则北,然后在動(dòng)畫的每一幀完成之后發(fā)布這個(gè)事件。在異步編程中使用發(fā)布—訂閱模式痕慢,我們就無需過多關(guān)注對(duì)象在異步運(yùn)行期間的內(nèi)部狀態(tài)尚揣,而只需要訂閱感興趣的事件發(fā)生點(diǎn)。
第二點(diǎn)說明發(fā)布—訂閱模式可以取代對(duì)象之間硬編碼的通知機(jī)制掖举,一個(gè)對(duì)象不用再顯式地調(diào)用另外一個(gè)對(duì)象的某個(gè)接口惑艇。發(fā)布—訂閱模式讓兩個(gè)對(duì)象松耦合地聯(lián)系在一起,雖然不太清楚彼此的細(xì)節(jié)拇泛,但這不影響它們之間相互通信。當(dāng)有新的訂閱者出現(xiàn)時(shí)思灌,發(fā)布者的代碼不需要任何修改俺叭;同樣發(fā)布者需要改變時(shí),也不會(huì)影響到之前的訂閱者泰偿。只要之前約定的事件名沒有變化熄守,就可以自由地改變它們。
3耗跛、Dom事件
實(shí)際上裕照,只要我們?cè)?jīng)在 DOM 節(jié)點(diǎn)上面綁定過事件函數(shù),那我們就曾經(jīng)使用過發(fā)布—訂閱模式
4调塌、自定義事件
發(fā)布-訂閱模式步驟
? 首先要指定好誰充當(dāng)發(fā)布者(比如售樓處) 晋南;
? 然后給發(fā)布者添加一個(gè)緩存列表, 用于存放回調(diào)函數(shù)以便通知訂閱者 (售樓處的花名冊(cè)) 羔砾;
? 最后發(fā)布消息的時(shí)候负间,發(fā)布者會(huì)遍歷這個(gè)緩存列表,依次觸發(fā)里面存放的訂閱者回調(diào)函數(shù)(遍歷花名冊(cè)姜凄,挨個(gè)發(fā)短信) 政溃。
var salesOffices = {}; // 定義售樓處
salesOffices.clientList = []; // 緩存列表,存放訂閱者的回調(diào)函數(shù)
salesOffices.listen = function( fn ){ // 增加訂閱者
this.clientList.push( fn ); // 訂閱的消息添加進(jìn)緩存列表
};
salesOffices.trigger = function(){ // 發(fā)布消息
for( var i = 0, fn; fn = this.clientList[ i++ ]; ){
fn.apply( this, arguments ); // (2) // arguments 是發(fā)布消息時(shí)帶上的參數(shù)
}
};
下面我們來進(jìn)行一些簡(jiǎn)單的測(cè)試:
salesOffices.listen( function( price, squareMeter ){ // 小明訂閱消息
console.log( '價(jià)格= ' + price );
console.log( 'squareMeter= ' + squareMeter );
});
salesOffices.listen( function( price, squareMeter ){ // 小紅訂閱消息
console.log( '價(jià)格= ' + price );
console.log( 'squareMeter= ' + squareMeter );
});
salesOffices.trigger( 2000000, 88 ); // 輸出:200 萬态秧,88 平方米
salesOffices.trigger( 3000000, 110 ); // 輸出:300 萬董虱,110 平方米