在 js 中應用 訂閱釋出模式(subscrib/public)
阿新 • • 發佈:2018-11-01
什麼是釋出-訂閱者模式
我們在使用釋出-訂閱者模式之前,先了解什麼是釋出-訂閱者模式。簡單來說,釋出訂閱者模式就是一種一對多的依賴關係。多個訂閱者(一般是註冊的函式)同時監聽同一個資料物件,當這個資料物件發生變化的時候會執行一個釋出事件,通過這個釋出事件會通知到所有的訂閱者,使它們能夠自己改變對資料物件依賴的部分狀態。
這樣看來,一個完整的訂閱釋出模式,由釋出者、訂閱者、訊息管理器三部分組成。
我們 為什麼/什麼時候 要使用這種模式
首先,如果一個數據或者事件的變化會對許多事件產生影響。例如:我們通過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會相繼執行更新自己的資料。