本文實例講述了JavaScript實現與使用發布/訂閱模式。分享給大家供大家參考,具體如下:
讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業的熱愛。我們立志把好的技術通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領域值得信任、有價值的長期合作伙伴,公司提供的服務項目有:域名注冊、雅安服務器托管、營銷軟件、網站建設、新絳網站維護、網站推廣。一、發布/訂閱模式簡介
發布/訂閱模式(即觀察者模式): 設計該模式背后的主要動力是促進形成松散耦合。在這種模式中,并不是一個對象調用另一個對象的方法,而是一個訂閱者對象訂閱發布者對象的特定活動,并在發布者對象的狀態發生改變后,訂閱者對象獲得通知。訂閱者也稱為觀察者,而被觀察的對象稱為發布者或主題。當發生了一個重要的事件時,發布者將會通知(調用)所有訂閱者,并且可能經常以事件對象的形式傳遞消息。
基本思路:發布者對象需要一個數組類型的屬性,以存儲所有的訂閱者。訂閱(即注冊)就是將新的訂閱者加入到這個數組中去,而注銷即是從這個數組中刪除某個訂閱者。此外,發布消息就是循環遍歷訂閱者列表并通知他們。
二、如何發布訂閱者的方法?
這里我的大體思路是對的。不過當時面試時,我還說了“在發布者之外,還需要定義了一個新的類——訂閱者。在訂閱者中,需要定義了一個類似 getNews 的方法,以便在發布者發布消息時,調用該方法”。然后,面試官說這樣太麻煩了,萬一訂閱者沒有這個方法呢?然后,我不是很懂……
于是我就想到了,在發布消息時直接傳遞了參數:obj.news = msg;
然后面試官說這樣不是更麻煩了嗎?這樣的話,如果訂閱者沒有 news 這個屬性怎么辦?還得判斷訂閱者是否有 news 這個屬性,沒有的話就會出現 undifined 的報錯。
然后,我就不知道該怎么做了……然后面試官為人特別 nice ,告訴我“可以用繼承或者是在注冊時候就傳入一個 function ”。
面試完后,回家上網查相關知識,整理出的注意點如下:
subscribers:一個數組,存儲訂閱者;subscribe()
:注冊/訂閱,將訂閱者添加到 subscribers 數組中;unsubscribe()
:取消訂閱。從 subscribers 數組中刪除訂閱者;publish()
:循環遍歷 subscribers 數組中的每一個元素,并且調用它們注冊時所提供的方法;
所有這三種方法都需要一個 type 參數。這是因為發布者可能觸發多個事件(比如同時發布一本雜志和一份報紙),而訂閱者可能僅選擇訂閱其中一種,而另外一種不訂閱。
三、代碼實現
參考《 JavaScript 模式》一書,使用字面量實現代碼如下:
// 由于這些成員對于任何發布者對象都是通用的,故將它們作為獨立對象的一個部分來實現是很有意義的。那樣我們可將其復制到任何對象中,并將任意給定對象變成一個發布者。 // 如下實現一個通用發布者,定義發布者對象…… let publisher = { subscribers: { any: [] }, subscribe: function (fn, type = `any`) { if (typeof this.subscribers[type] === `undefined`) { this.subscribers[type] = []; } this.subscribers[type].push(fn); }, unSubscribe: function (fn, type = `any`) { let newSubscribers = []; this.subscribers[type].forEach((item, i) => { if (item !== fn) { newSubscribers.push(fn); } }); this.subscribers[type] = newSubscribers; }, publish: function (args, type = `any`) { this.subscribers[type].forEach((item, i) => { item(args); }); } }; // 定義一個函數makePublisher(),它接受一個對象作為參數,通過把上述通用發布者的方法復制到該對象中,從而將其轉換為一個發布者 function makePublisher(obj) { for (let i in publisher) { if (publisher.hasOwnProperty(i) && typeof publisher[i] === `function`) { obj[i] = publisher[i]; } } obj.subscribers = { any: [] }; } // 實現paper對象 var paper = { daily: function () { this.publish(`big news today!`); }, monthly: function () { this.publish(`interesting analysis`, `monthly`); } }; // 將paper構造成一個發布者 makePublisher(paper); // 看看訂閱對象joe,該對象有兩個方法: var joe = { drinkCoffee: function (paper) { console.log(`Just read ` + paper); }, sundayPreNap: function (monthly) { console.log(`About to fall asleep reading this ` + monthly); } }; // paper注冊joe(即joe向paper訂閱) paper.subscribe(joe.drinkCoffee); paper.subscribe(joe.sundayPreNap, `monthly`); // 即joe為默認“any”事件提供了一個可被調用的方法,而另一個可被調用的方法則用于當“monthly”類型的事件發生時的情況。現在讓我們來觸發一些事件: paper.daily(); // Just read big news today paper.daily(); // Just read big news today paper.monthly(); // About to fall asleep reading this interesting analysis paper.monthly(); // About to fall asleep reading this interesting analysis paper.monthly(); // About to fall asleep reading this interesting analysis
當前文章:JavaScript實現與使用發布/訂閱模式詳解-創新互聯
轉載來于:http://vcdvsql.cn/article6/csgoog.html
成都網站建設公司_創新互聯,為您提供網站制作、外貿建站、虛擬主機、電子商務、搜索引擎優化、網站設計
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯