Показать сообщение отдельно
  #16 (permalink)  
Старый 30.01.2016, 14:54
Профессор
Отправить личное сообщение для tsigel Посмотреть профиль Найти все сообщения от tsigel
 
Регистрация: 12.12.2012
Сообщений: 1,398

GayCoder,
Увы, но данная реализация вообще не верна и не имеет права на жизнь.
Дело в том что вы в подписке проверяете наличие этой функции в слушателе чего делать категорически нельзя. Допустим у меня есть 2 экземпляра одного класса, и оба подписываются на событие, если метод которым они подписываются лежит в прототипе, то первый подпишется нормально, а второй перетрет его scope (в вашей реализации). Я создал упрощённый макет чтобы продемонстрировать ошибку:

var EventEmiter = {
    _handlers: [],
    on: function (handler, context) {
        if (!this._hasHandler(handler)) {
            this._handlers.push({handler: handler, context: context});
        }
    },
    off: function (handler) {
        this._handlers.splice(this._handlers.indexOf(handler), 1);
    },
    emit: function () {
        this._handlers.slice().forEach(function (handlerData) {
            handlerData.handler.call(handlerData.context);
        });
    },
    _hasHandler: function (handler) {
        return this._handlers.some(function (handlerData) {
            return handlerData.handler === handler;
        });
    }
};

var SomeClass = function (name) {
    this._name = name;
};

SomeClass.prototype.onEvent = function () {
    console.log(this._name);
};

var vasia = new SomeClass('Вася');
var petia = new SomeClass('Петя');

EventEmiter.on(vasia.onEvent, vasia);
EventEmiter.on(petia.onEvent, petia);

EventEmiter.emit();


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

Ну и в методе emit вы почему-то снова не скопировали массив обработчиков перед тем как вызывать события.

Последний раз редактировалось tsigel, 30.01.2016 в 14:59.
Ответить с цитированием