Created
October 21, 2018 21:24
-
-
Save codyfet/32eb14250d82ea401bae0894ea7e9a2e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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