Опубликовать / подписаться на уведомление после публикации

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

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

* ИЗМЕНИТЬ 1 *

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

* ИЗМЕНИТЬ 2 *

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


person chchrist    schedule 26.07.2011    source источник


Ответы (1)


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

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

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

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

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