Задать вопрос
Tpona
@Tpona
Ужасный перфекционист

Почему не верный размер массива?

Есть обект:
/*
 * Класс реализующий события для объекта
 */
function DashboardEventEmitter() {
    this.events = {};
};

/*
 * Регистрируем события поддерживаемые объектом
 * Функция вызывается в конструкторе класса
 * @param event (string) название события
 */
DashboardEventEmitter.prototype.registerEvent = function(event) {
    if (this.events.hasOwnProperty(event))
        throw Error('Попытка зарегистрировать событие, которое уже было зарегистрировано');
    this.events[event] = new Array();
    console.log(this.events); 
}

/*
 * Навешивает обработчик на событие
 * @param event (string) название события
 * @param callback (function) внешняя функция-обработчик
 */
DashboardEventEmitter.prototype.on = function(event, callback) {
    if (!this.events.hasOwnProperty(event))
        throw Error('Попытка назначить незарегистрированное событие');
    this.events[event].push(callback);
}
    
/*
 * Инициирует событие
 * @param event (string) название события
 * @param data (object) объект с данными
 */
DashboardEventEmitter.prototype.emit = function(event, data) {
    console.log('try to emit event '+event);
    if (!this.events.hasOwnProperty(event))
        throw Error('Попытка вызвать незарегистрированное событие');
    
    console.log(this.events);
    console.log(this.events[event][0]);
    
    for (var i = 0; i < this.events[event].length; i++) {
        var callback = this.events[event][i];
        callback.call(this, data); 
    }
}


Наследуемся и используем:
/*
 * Источник данных, пока только из таблиц
 * позже будет наследование и переопределение функций для разных типов источников
 */

function DashboardDataSource(options) {
    DashboardEventEmitter.apply(this, arguments);
    options = options ? options : {};
    this.paramNames = ["Объект", "ПсевдонимСист", "ТаблицаId", "ТипОбъекта"];
    this.fields = [];
    this.table = null;
    
    this.registerEvent('ready');
    this.registerEvent('created');
    
    // Если в конструктор пришли правильные данные - загружаем из них
    
    if (options.hasOwnProperty('table') && options.hasOwnProperty('fields'))  {
        this.setData(options);
    }
    
}

DashboardDataSource.prototype = Object.create(DashboardEventEmitter.prototype);
DashboardDataSource.prototype.constructor = DashboardEventEmitter;

/*
 * Данные таблицы (поля и их метаинформация)
 */
DashboardDataSource.prototype.setData = function(data) {
/*
    this.table = data.table;
    this.validateTableData(data.table);
    for (var i = 0; i < data.fields.length; i++) {
        this.fields.push(new DashboardDataSourceField(data.fields[i]));
    }
*/
    this.emit('ready', {value:true});
}

/*
 * Проверяем целостновть пришедших данных
 */
DashboardDataSource.prototype.validateTableData = function(data) {
    for (var i = 0; i < this.paramNames.length; i ++ ) {
        if (!data.hasOwnProperty(this.paramNames[i]))
            throw Error('Отсутствует необходимое описание таблицы "'+this.paramNames[i]+'"');
    }
    return true;
}

/*
 * Получить системный псевдоним
 */
DashboardDataSource.prototype.getPseudonimSyst = function() {
    return this.table['ПсевдонимСист'];
}

/*
 * Тип источника данных (пока только таблица)
 */
DashboardDataSource.prototype.getType = function() {
    return 'table';
}

DashboardDataSource.prototype.load = function() {

}

/*
 * Конвертируем в объект для последующего сохранения в базу описания дашборда
 */
DashboardDataSource.prototype.toObject = function() {
    var result = {};

    result.table    = table; 
    result.fields   = [];

    for (var i = 0; i < this.fields.length; i++ ) {
        result.fields.push(this.fields[i].toObject());
    }

    return result; 
}



var ds = new DashboardDataSource({});
ds.on('ready', function(object, data){
alert('heahh!')
})


Вопрос 1: Почему в функции emit базового прототипа events.ready.length = 0; хотя функция там есть, не должен быть равен нулю
Вопрос 2: Это ведь велосипед?
  • Вопрос задан
  • 213 просмотров
Подписаться 1 Оценить 8 комментариев
Решения вопроса 1
@vshvydky
По теме 1.
Замени push на равно. Объяснить не могу, но это сработает. Не думаю, что тебе на 1 обработчик потребуется несколько функций. Возможно балуется сборщик мусора, так как в отладке функцию в массив складывает.
this.events[event] = callback
По теме 2.
Можно позаимсововать код EventEmmiter для node.js
Про велосипедность, да пахнет велосипедом. На мой взгляд избыточным смотрится наследование с передачей опций вникуда, а еще отдельный метод для регистрации события. Этот функционал должен быть включен в on. Так же неплохо иметь методы просмотра списка событий и удаление.
А еще не совсем понимаю, как ты передашь в функцию параметры, которая попала в on. Посмотри в ноде доки, там параметры передаются после функции как аргументы.
Апдейт, нарисовал чуток кода. Возможно это вам нужно.
class Emitter {
    constructor() {
        this.events = {};
    }

    on(event, cb) {
        console.log('[ON]Проверяем есть ли массив функций: ' + (this.events[event] instanceof Array));
        if (!(this.events[event] instanceof Array)) {
            console.log('[ON]Создаем массив для ' + event);
            this.events[event] = [];
        }
        this.events[event].push(cb);
        console.log('[ON]В событие: ' + event + ' добавлена функция: ' + cb);
    }

    emit(event, arg) {
        try {
            if (!this.events.hasOwnProperty(event))
                throw Error('Попытка вызвать незарегистрированное событие');
            console.log('[EMIT]Проверяем в эмите ' + (this.events[event] instanceof Array));
            this.events[event].forEach(function (item) {
                console.log('[EMIT]Выполняем событие: ' + item + ' для аргумента: ' + arg);
                item(arg);
            });
        } catch (e) {
            console.log('Отловили ошибку: ' + e.message);
        }
    }
}
let fu1 = function (arg) {
    console.log('[FUNCTION]Выполняется первая функция из эмиттера, значение аргумента ' + arg);
};
let fu2 = function (arg) {
    console.log('[FUNCTION]Выполняется вторая функция из эмиттера, значение аргумента ' + arg);
};
let obj1 = new Emitter();
obj1.on('run', fu1);
obj1.on('run', fu2);
obj1.emit('run', 'hellooooo!!!');
obj1.emit('run', 'hef3efgw2llooooo!!!');
obj1.emit('rune', 'hef3efgw2llooooo!!!');

Результат исполнения:
[ON]Проверяем есть ли массив функций: false
[ON]Создаем массив для run
[ON]В событие: run добавлена функция: function (arg) {
    console.log('[FUNCTION]Выполняется первая функция из эмиттера, значение аргумента ' + arg);
}
[ON]Проверяем есть ли массив функций: true
[ON]В событие: run добавлена функция: function (arg) {
    console.log('[FUNCTION]Выполняется вторая функция из эмиттера, значение аргумента ' + arg);
}
[EMIT]Проверяем в эмите true
[EMIT]Выполняем событие: function (arg) {
    console.log('[FUNCTION]Выполняется первая функция из эмиттера, значение аргумента ' + arg);
} для аргумента: hellooooo!!!
[FUNCTION]Выполняется первая функция из эмиттера, значение аргумента hellooooo!!!
[EMIT]Выполняем событие: function (arg) {
    console.log('[FUNCTION]Выполняется вторая функция из эмиттера, значение аргумента ' + arg);
} для аргумента: hellooooo!!!
[FUNCTION]Выполняется вторая функция из эмиттера, значение аргумента hellooooo!!!
[EMIT]Проверяем в эмите true
[EMIT]Выполняем событие: function (arg) {
    console.log('[FUNCTION]Выполняется первая функция из эмиттера, значение аргумента ' + arg);
} для аргумента: hef3efgw2llooooo!!!
[FUNCTION]Выполняется первая функция из эмиттера, значение аргумента hef3efgw2llooooo!!!
[EMIT]Выполняем событие: function (arg) {
    console.log('[FUNCTION]Выполняется вторая функция из эмиттера, значение аргумента ' + arg);
} для аргумента: hef3efgw2llooooo!!!
[FUNCTION]Выполняется вторая функция из эмиттера, значение аргумента hef3efgw2llooooo!!!
Отловили ошибку: Попытка вызвать незарегистрированное событие
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
abyrkov
@abyrkov
JavaScripter
Насчет второго - да, велосипед )
В jQuery есть реализация событий. Можете "списать"
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы