3

我想了解Observable/Observer設計模式。在發佈後發佈/訂閱通知

這是我到目前爲止(代碼從Javascript模式一書)代碼:

  var publisher = { 
      subscribers: { 
       any: [] // event type: subscribers 
      }, 
      publications: { 
       any: [] 
      }, 
      subscribe: function (fn, type) { 
       type = type || 'any'; 
       if (typeof this.subscribers[type] === "undefined") { 
        this.subscribers[type] = []; 
       } 

       this.subscribers[type].push(fn); 

       if(typeof this.publications[type] === "undefined"){ 
        return; 
       } 

       var pubs = this.publications[type], 
       i, 
       max = pubs.length 

       for(i = 0;i<max;i++){ 
        this.subscribers[type][i](pubs[i]); 
       } 

      }, 
      unsubscribe: function (fn, type) { 
       this.visitSubscribers('unsubscribe', fn, type); 
      }, 
      publish: function (publication, type) { 
       var pubtype = type || 'any'; 
       this.visitSubscribers('publish', publication, type); 
       if(typeof this.publications[pubtype] === "undefined") { 
        this.publications[pubtype] = []; 
       } 
       this.publications[pubtype].push(publication); 
      }, 
      visitSubscribers: function (action, arg, type) { 
       var pubtype = type || 'any', 
       subscribers = this.subscribers[pubtype], 
       i, 
       max; 

       if(typeof subscribers === 'undefined') { 
        return; 
       } 

       max = subscribers.length; 

       for (i = 0; i < max; i += 1) { 
        if (action === 'publish') { 
         subscribers[i](arg); 
        } else { 
         if (subscribers[i] === arg) { 
          subscribers.splice(i, 1); 
         } 
        } 
       } 
      } 
     }; 

     function makePublisher(o) { 
      var i; 
      for (i in publisher) { 
       if (publisher.hasOwnProperty(i) && typeof publisher[i] === "function") { 
        o[i] = publisher[i]; 
       } 
      } 
      o.subscribers = {any: []}; 
      o.publications = {any: []}; 
     } 

     var paper = { 
      daily: function() { 
       this.publish("big news today"); 
      }, 
      monthly: function() { 
       this.publish("interesting analysis", "monthly"); 
      }, 
      yearly: function() { 
       this.publish("every year","yearly"); 
      } 
     }; 

     makePublisher(paper); 

     var joe = { 
      drinkCoffee: function (paper) { 
       console.log('Just read ' + paper); 
      }, 
      sundayPreNap: function (monthly) { 
       console.log('About to fall asleep reading this ' + monthly); 
      }, 
      onHolidays: function(yearly) { 
       console.log('Holidays!'+yearly); 
      } 
     }; 


     paper.daily(); 
     paper.monthly(); 
     paper.yearly(); 

     paper.subscribe(joe.drinkCoffee); 
     paper.subscribe(joe.onHolidays,'yearly'); 
     paper.subscribe(joe.sundayPreNap, 'monthly'); 

我不知道是否有可能以某種方式使客戶能夠獲得通知 即使他們後註冊自己這些通知已被播出。

我應該修改publisher.subscribe並使其檢查是否未定義,如果是發佈事件類型?

在此先感謝。

* 編輯1 *

我添加了一個出版物對象保存在發佈功能的出版物。我也檢查是否有訂閱者的發佈類型,如果沒有,我打電話回報。現在我需要弄清楚如何通知他們有關訂閱的較早發佈。

* EDIT 2 *

工作腳本的新版本中添加。它認爲是正確的還是最好的辦法?

回答

1

如果你希望允許用戶得到通知發送之後,您需要做的僅僅是

  1. 對於每個不同的出版物類型,保存所有通知你得到它的列表。 (發佈時,將publication添加到適當的列表中)

  2. 更改訂閱功能,以便它還將所有適當的存儲通知發送到遲到的訂閱者。

    2.1也許你還應該創建一個單獨的send_notification_to(arg, type, subscriber)方法,以避免與visitSubscribers

+0

我已經修改了發佈對象保存出版物代碼duplicatio。這是正確的嗎?我正在嘗試着邁出第二步。問題在於paper.yearly()被調用時。這將調用publisher.publish,但沒有訂閱者,因此它返回undefined。也許我應該檢查發佈方法,如果有這種類型的用戶?真的很困惑... – chchrist

+0

你的腳本似乎在爲我工作... – hugomg