前端JavaScript的發佈-訂閱模式

發佈-訂閱模式又被稱爲觀察者模式,它是定義在對象之間一對多的關係中,當一個對象發生變化,其餘依賴於它的對象收到通知。在javascript的開發中,咱們通常用事件模型替代發佈-訂閱模式。

DOM事件

document.body.addEventListener('click',function(){

    alert(綁定1);

},false)};
複製代碼

document.body.click();  //模擬點擊
 
document.body.addEventListener('click',function(){

    alert(綁定2);

},false)};
 
document.body.addEventListener('click',function(){

    alert(綁定3);
 
},false)};
 
document.body.click();  //模擬點擊
複製代碼

咱們能夠增長更多訂閱者,不會對發佈者的代碼形成影響。注意,標準瀏覽器下用dispatchEvent實現。javascript

自定義事件

①肯定發佈者。(例如售票處)java

②添加緩存列表,便於通知訂閱者。(預訂車票列表)設計模式

③發佈消息。遍歷緩存列表。依次觸發裏面存放的訂閱者回調函數(遍歷列表,逐個發送短信)。瀏覽器

另外,咱們還能夠在回調函數填入一些參數,例如車票的價格之類信息。緩存

var ticketOffice = {};    //售票處

ticketOffice.clientList = [];    //緩存列表,存放訂閱者的回調函數

ticketOffice.listen = function (fn) {    //增長訂閱者
    this.clientList.push(fn);    //訂閱的消息添加進緩存列表
};

ticketOffice.trigger = function () {    //發佈消息
    for(var i = 0, fn; fn = this.clientList[i++];){
        fn.apply(this, arguments);    //arguments 是發佈消息時帶上的參數
    }
}

下面進行簡單測試:

ticketOffice.listen(function(time, path){    //小剛訂閱消息
    console.log('時間:' + time);
    console.log('路線:' + path);
});


ticketOffice.listen(function(time, path){    //小強訂閱消息
    console.log('時間:' + time);
    console.log('路線:' + path);
});

ticketOffice.trigger('晚上8:10','深圳-上海');
ticketOffice.trigger('晚上8:10','上海-深圳');
複製代碼

至此,咱們實現了一個最簡單發佈-訂閱模式。不過這裏存在一些問題,咱們運行代碼能夠看到訂閱者接收到了全部發布的消息。咱們有必要加個key讓訂閱者只訂閱 本身感興趣的消息。改寫後的代碼以下:
bash

var ticketOffice = {};    //售票處

ticketOffice.clientList = [];    //緩存列表,存放訂閱者的回調函數

ticketOffice.listen = function (key, fn) {    //增長訂閱者
    if (!this.clientList[key]){
        this.clientList[key] = [];
    }
    this.clientList[key].push(fn);    //訂閱的消息添加進緩存列表
};

ticketOffice.trigger = function () {    //發佈消息
    var key = Array.prototype.shift.call(arguments),    //取出消息類型
        fns = this.clientList[key];    //取出該消息對應的回調函數集合
    if (!fns || fns.length === 0) {
        return false;
    }

    for(var i = 0, fn; fn = fns[i++];){
        fn.apply(this, arguments);    //arguments 是發佈消息時帶上的參數
    }
}

ticketOffice.listen('上海-深圳', function(time){    //小剛訂閱消息
    console.log('小剛時間:' + time);
});


ticketOffice.listen('深圳-上海', function(time){    //小強訂閱消息
    console.log('小強時間:' + time);
});

ticketOffice.trigger('深圳-上海', '晚上8:00');
ticketOffice.trigger('上海-深圳', '晚上8:10');
複製代碼

這樣子,訂閱者就能夠只訂閱本身感興趣的事件了。app

參考資料

《JavaScript 設計模式與開發實踐》函數

相關文章
相關標籤/搜索