3

Я пытаюсь понять шаблон проектирования Observable/Observer.Опубликовать/Подпишитесь на уведомление после опубликования

Это код, который я до сих пор (код из Javascript Patterns книги):

  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 и заставить ее проверить, не определены ли и если да, опубликовать тип события?

Заранее спасибо.

* EDIT 1 *

Я добавил публикации объекта для сохранения публикаций в функции публикации. Я также проверяю, есть ли подписчики для типа публикации, и если я не вызываю возврат. Теперь мне нужно выяснить, как уведомить их о более ранней публикации на подписке.

* EDIT 2 *

Новая версия рабочего скрипта добавлена. Считается ли это правильным или лучшим способом сделать это?

ответ

1

Если вы хотите, чтобы позволить абонентам получать уведомления после того, как они будут отправлены, что вам нужно сделать, это просто

  1. Для каждого типа публикации, сохранить список всех уведомлений, которые вы получите за это. (При публикации добавьте publication в соответствующий список)

  2. Изменить функцию подписки, чтобы она также отправила все соответствующие сохраненные уведомления последнему абоненту.

    2.1 Возможно, вы также должны создать отдельный send_notification_to(arg, type, subscriber) метод, чтобы избежать кода duplicatio с visitSubscribers

+0

Я модифицировал публиковать объект для сохранения публикаций. Правильно ли это? Сейчас я пытаюсь сделать второй шаг. Проблема заключается в том, когда вызывается paper.yearly(). Это вызывает publisher.publish, но нет подписчиков, поэтому он возвращает undefined. Может быть, я должен проверить метод публикации, если есть такие подписчики этого типа? Действительно запутался ... – chchrist

+0

Ваш скрипт, похоже, работает на меня ... – hugomg

Смежные вопросы