Skip to content

Instantly share code, notes, and snippets.

@codyfet
Created October 21, 2018 21:24
Show Gist options
  • Save codyfet/32eb14250d82ea401bae0894ea7e9a2e to your computer and use it in GitHub Desktop.
Save codyfet/32eb14250d82ea401bae0894ea7e9a2e to your computer and use it in GitHub Desktop.
var students = {
Ang: {
focus: 90,
wisdom: 90
},
Jana: {
focus: 00,
wisdom: 50
}
};
var lecturer = {
events: {}, // Мапа вида: [имя_события]: [массив функций обработчиков, вызываемых в момент наступления события], пример: {'begin': [() => {...}, () => {...}]}
/**
* Метод, который подписывает объект на событие и устанавливает функцию-обработчик.
*
* @param {Object} eventName Имя события.
* @param {Object} eventObject Объект, который подписывается на событие.
* @param {Function} eventAction Функция-обработчик, которая будет вызываться для объекта в момент наступления события.
*/
on: function (eventName, eventObject, eventAction) {
// Если для данного события ещё нет ни одного обработчика, то создаём пустой массив обработчиков.
if (!this.events[eventName]) {
this.events[eventName] = [];
}
// Кладём в массив обработчиков функцию-обёртку, которая будет вызывать обработчик для конкретного объекта.
this.events[eventName].push((isUnsubscribe) => {
// Применяем обработчик.
// Флаг isUnsubscribe нужен, чтобы при отписке от события методом off не выполнять функцию-обработчик.
if (!isUnsubscribe) {
eventAction.apply(eventObject);
}
// Функция-обёртка всегда возвращает ссылку на подписанный объект.
// Это пригодится нам, когда мы будем отписывать объект от события методом off.
return eventObject;
});
},
/**
* Метод, который отписывает объект от события и удаляет все функции-обработчики.
*
* @param {Object} eventName Имя события.
* @param {Object} eventObject Объект, который отписывается от события.
*/
off: function (eventName, eventObject) {
// Оставляем только тех обработчиков, которые не имеют отношения к отписываемому объекту.
this.events[eventName] = this.events[eventName].filter((wrapperFn) => {
// Функция-обёртка, как мы помним, возвращает ссылку на подписанный объект.
// Это позволяет нам провести вычисление и оставить все функции-обработчики, кроме принадлежащих отписываемому объекту.
// Так и происходит отписывание.
const resultEventObject = wrapperFn(true);
return resultEventObject != eventObject;
});
},
/**
* Метод, который тригеррит событие. Вызываются все обработчики данного события для всех подписанных объектов.
*
* @param {Object} eventName Имя события.
*/
emit: function (eventName) {
this.events[eventName].forEach((wrapperFn) => {
wrapperFn();
});
}
}
// *** Тест
lecturer.on('begin', students.Ang, function () {
// Внимательно слушаем преподавателя
this.focus += 10;
});
lecturer.on('slide', students.Ang, function () {
// И впитываем мудрость с каждым слайдом
this.wisdom += 10;
});
console.log("Параметр wisdom изначально равен:");
console.log(students.Ang.wisdom);
console.log("*** Наступает событие begin");
lecturer.emit('begin');
console.log("*** Наступает событие slide");
lecturer.emit('slide');
console.log("Параметр wisdom теперь равен:");
console.log(students.Ang.wisdom);
console.log("Отписываемся от события slide:");
lecturer.off('slide', students.Ang);
console.log("*** Наступает событие slide");
console.log("*** Наступает событие slide");
lecturer.emit('slide');
lecturer.emit('slide');
console.log("Параметр wisdom теперь равен:");
console.log(students.Ang.wisdom);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment