js觀察者模式發佈/訂閱

實習期結束,最近回到學校開始學習node.js,node果真是強大。不過在涉及到文件操做的時候,發現要大量使用異步回掉操做。node

之前在寫頁面的時候,從沒這麼多異步操做,只有在使用'setInterval'和'XMLHttpRequest'時瞭解了一下異步編程。此次在學習node的過程當中,把異步回掉算是弄清楚了。可是在編碼書寫代碼的時候,陷入了回調金字塔(callback hell)。使用es6Promise解決了一些問題。也看到了EventProxy模塊基於事件驅動的解決方案。es6

在使用EventProxy的過程當中,有種似曾相識的感受。有點像觀察者模式發佈/訂閱。首先使用數組緩存訂閱者訂閱的消息,當訂閱者訂閱消息的時候,把訂閱的消息push到指定消息的隊列中,當發佈者發佈消息的時候,咱們遍歷執行push到指定消息隊列中的回調事件。編程

而訂閱者不須要關心發佈者何時發佈消息。
而發佈者不須要關心訂閱者訂閱的狀態。數組

var observer = new Observe();
var callback = function(num) {
    console.log("event:"+num); // 輸出event:2
};
// 訂閱消息
observer.listen("event1", callback);
observer.listen("event2", callback);
// 移除訂閱消息1
observer.remove('event1', callback);
// 發佈者發佈消息
observer.trigger("event1",1);
observer.trigger("event2",2);

具體代碼以下:緩存

function Observe() {
    // 緩存訂閱者的消息隊列
    this._list = [];
}
/**
 *
 * 訂閱者訂閱消息
 * @param  {string}   key 消息名
 * @param  {Function} fn  回調事件
 * @return {Null}       
 */
Observe.prototype.listen = function(key, fn) {
    if (!this._list[key]) {
        this._list[key] = [];
    }
    // 訂閱消息,添加到緩存列表中
    this._list[key].push(fn);
};
/**
 * 
 * 移除訂閱的消息
 * @param  {string}   key 消息名
 * @param  {Function} fn  回掉事件
 * @return {Null}       
 */
Observe.prototype.remove = function(key, fn) {
    // 獲取當前key下的消息記錄
    var arrFn = this._list[key];
    if (!arrFn) return false;
    // 未指定fn則刪除當前key下全部的訂閱消息
    if (!fn) {
        arrFn.length = 0;
    } else {
        for (var i = 0; i < arrFn.length; i++) {
            if (fn === arrFn[i]) {
                arrFn.splice(i,1);
            }
        }
    }
};
/**
 * 發佈者發佈消息
 * @param  {string} key 消息名
 * @param  {string | Object} 消息數據
 * @return {Null}  
 */
Observe.prototype.trigger = function() {
    // 獲得key,第二個及以上的參數
    var key = Array.prototype.shift.call(arguments);
    var args = arguments;
    var arrFn = this._list[key];
    if (!arrFn || arrFn.length === 0) {
        return;
    }
    // 遍歷執行當前key下面的全部消息
    for (var i = 0; i < arrFn.length; i++) {
        arrFn[i].apply(this, args);
    }
};
相關文章
相關標籤/搜索