1. 程式人生 > >在 js 中應用 訂閱釋出模式(subscrib/public)

在 js 中應用 訂閱釋出模式(subscrib/public)

什麼是釋出-訂閱者模式

我們在使用釋出-訂閱者模式之前,先了解什麼是釋出-訂閱者模式。簡單來說,釋出訂閱者模式就是一種一對多的依賴關係。多個訂閱者(一般是註冊的函式)同時監聽同一個資料物件,當這個資料物件發生變化的時候會執行一個釋出事件,通過這個釋出事件會通知到所有的訂閱者,使它們能夠自己改變對資料物件依賴的部分狀態。
這樣看來,一個完整的訂閱釋出模式,由釋出者、訂閱者、訊息管理器三部分組成。

釋出-訂閱者模式

我們 為什麼/什麼時候 要使用這種模式

首先,如果一個數據或者事件的變化會對許多事件產生影響。例如:我們通過websocket從後臺實時獲取資料,當返回的資料為 @end 時,需要執行關閉資料流,更改資料顯示,更新裝置狀態等等,在不使用訂閱開發者模式時,當接收到 @end 後,我們註冊一個函式,需要在該函式中寫n個函式的執行,但是使用設計者模式,只需要註冊一個 @end 的釋出函式,其他函式訂閱該函式,當釋出函式執行後會釋出資訊,其訂閱者會自動更新狀態。

  • 耦合性低
  • 便於程式碼的維護
在js中的實現

所有程式碼都在專案中親測有效,且效率較高

1. 定義一個釋出者物件,該物件有訂閱者列表和釋出函式兩個屬性。
function Deliver() {
  this.subscribers = [];
}
Deliver.prototype = {
  constructor: Deliver,
  deliver: function( message ) {
    this.subscribers.forEach( function( fun ) {
      fun( message )
; } ); return this; } }
2. 為釋出者物件新增訂閱方法和退訂方法
//訂閱事件
function subscribe( subscriber, deliver ) {
  var hasExists = false,
  isFunction = Object.prototype.toString.call( subscriber ) === '[object Function]';
  if( isFunction && deliver instanceof Deliver ) {
      hasExists = deliver.
subscribers.some( function( fun ) { return fun === subscriber; } ); if( !hasExists ) { deliver.subscribers.push( subscriber ); } } } //退訂subscriber事件 function unSubscribe( subscriber, deliver ) { var isFunction = Object.prototype.toString.call( subscriber ) === '[object Function]'; if( isFunction && deliver instanceof Deliver ) { deliver.subscribers = deliver.subscribers.filter( function( fun ) { return fun !== subscriber; } ) } }
3. 例項化一個釋出者併為其新增訂閱者
var endDeliver = new endDeliver();
(function(window){
   subscriber(endHandle , endDeliver);
    subscriber(endHandle2 , endDeliver);
	if(webSocket.data == "@end"){
  			endDeliver.deliver();//當返回資料為end時,end釋出者釋出訊息
  		}
})(window)
function endHandle(){
		console.log("已執行結束")
    }
    function endHandle2(){
	console.log("重新開始執行函式");
}
4. 執行結果

執行結果

四、應用心得
  • 可以註冊一個空的釋出者,即在滿足某些條件時釋出一些空訊息,而訂閱者的執行也不需要傳遞任何的引數。主要適用於狀態的改變引起的函式執行。
  • 註冊帶有引數的釋出者,當資料改變時,將資料作為引數傳遞給各個訂閱者,訂閱者根據返回的資料進行狀態的更新。主要適用於對資料的渲染及判斷。
//例項化一個數據釋出者
var messagePost = new Deliver();
//該釋出者有兩個訂閱者
subscriber(handle1 , messagePost);
subscriber(handle2 , messagePost);
//兩個訂閱者分別執行的函式為
function handle1(data){
	console.log(data);
}
function handle2(data){
	$(".dome").html(data.ip);
}
//在資料發生改變的時候釋出者釋出訊息
websocket.onmessage = function(evet){
	messagePost.deliver(event.data)
}
//執行結果
當通過websocket返回的資料時,messagePost會發布訊息,handle1 handle2會相繼執行更新自己的資料。
第一次大規模的在專案中使用設計模式,所以把思路整理分享一下,有不對的地方還望大家能夠指出。