From b7b3dc4b66c28623163a82bb8f55d8f1918e46fc Mon Sep 17 00:00:00 2001 From: Nikita Lebedev Date: Wed, 9 Nov 2016 18:41:26 +0500 Subject: [PATCH] star --- emitter.js | 65 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 5 deletions(-) diff --git a/emitter.js b/emitter.js index c17c92f..9fa6002 100644 --- a/emitter.js +++ b/emitter.js @@ -13,32 +13,85 @@ module.exports = getEmitter; */ function getEmitter() { return { + events: {}, /** * Подписаться на событие * @param {String} event * @param {Object} context * @param {Function} handler + * @returns {Object} */ on: function (event, context, handler) { - console.info(event, context, handler); + var times = arguments[3] || Infinity; + var frequency = arguments[4] || 1; + + if (!this.events[event]) { + this.events[event] = []; + } + + this.events[event].push({ + context: context, + handler: handler, + times: times, + timesCalled: 0, + frequency: frequency, + callHandler: function () { + if (this.timesCalled % this.frequency === 0 && this.timesCalled < this.times) { + this.handler.call(this.context); + } + this.timesCalled += 1; + } + }); + + return this; }, /** * Отписаться от события * @param {String} event * @param {Object} context + * @returns {Object} */ off: function (event, context) { - console.info(event, context); + Object.keys(this.events) + .filter(function (evt) { + return evt === event || evt.startsWith(event + '.'); + }) + .forEach(function (evt) { + this.events[evt] = this.events[evt].filter(function (listener) { + return listener.context !== context; + }); + }.bind(this)); + + return this; }, /** * Уведомить о событии * @param {String} event + * @returns {Object} */ emit: function (event) { - console.info(event); + var listeners = this.events[event]; + + if (listeners) { + listeners + .filter(function (listener) { + return listener.timesCalled !== listener.times; + }) + .forEach(function (listener) { + listener.callHandler(); + }); + } + + var subEventPosition = event.lastIndexOf('.'); + if (subEventPosition !== -1) { + event = event.substring(0, subEventPosition); + this.emit(event); + } + + return this; }, /** @@ -48,9 +101,10 @@ function getEmitter() { * @param {Object} context * @param {Function} handler * @param {Number} times – сколько раз получить уведомление + * @returns {Object} */ several: function (event, context, handler, times) { - console.info(event, context, handler, times); + return this.on(event, context, handler, times); }, /** @@ -60,9 +114,10 @@ function getEmitter() { * @param {Object} context * @param {Function} handler * @param {Number} frequency – как часто уведомлять + * @returns {Object} */ through: function (event, context, handler, frequency) { - console.info(event, context, handler, frequency); + return this.on(event, context, handler, undefined, frequency); } }; }