Антон Веретенников и Илья Семаков. Презентация
-
Upload
daria-oreshkina -
Category
Engineering
-
view
202 -
download
3
Transcript of Антон Веретенников и Илья Семаков. Презентация
Антон ВеретенниковИлья Семаков
«ПЕРЕХОД ОТ КОЛЛБЕКОВК СОБЫТИЯМ»
Public API
Frontend BackendAJAX
разработать frontend-часть для нового проекта заказчика
Задача:
Search
Results
Filter #1
1 2 ... N
Filter #2
разработать frontend-часть для нового проекта заказчика
Задача:
Frontend
Filter #3
Combobox
Sort
CheckboxCheckboxCheckbox
Checkbox
TitleLorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore
CheckboxCheckbox
Combobox
CheckboxCheckboxCheckbox
CheckboxCheckboxCheckbox
разработать frontend-часть для нового проекта заказчика
Задача:
Пути решения
Callback
разработать frontend-часть для нового проекта заказчика
Задача:
Event-driven
Пути решения
разработать frontend-часть для нового проекта заказчика
Задача:
Callback Event-driven
?
Пути решения
Component_1 = { update : function( callback ) { callback() }, reset : function( callback ){ callback() }};
Component_2 = { business : function(){ Component_1.update(this.callback); }, callback : function(){ ... }};
Callback
Сначала все выглядит вот так
Component_1 = { update : function( callback ) { callback() }, reset : function( callback ){ callback() }};
Component_2 = { business : function(){ Component_1.update(this.callback); }, callback : function(){ ... }};
Component_3 = { business : function(){ Component_1.reset(this.callback); }, callback : function(){ ... }};
Callback
Появляются новые требования
Component_1 = { update : function( callback ) { callback() }, reset : function( callback ){ callback() }};
Component_2 = { business : function(){ Component_1.update(this.callback); }, callback : function(){ ... }};
Component_3 = { business : function(){ Component_1.reset(this.callback); }, callback : function(){ ... }};
Component_4 = { business : function(){ Component_2.business(); }};
Callback
... и ещё
Callback
... а в итоге получаем
Callback
Хорошо работают на несложных проектах.—
— Слабая гибкость из-за постоянно возрастающих зависимостей.
Module_2
Component_3Manager
Event
Component_4
Module_1
Component_1
Component_2
Event-driven. Теория
Event-driven. Теория
Component_3 = { construct : function(){ Manager.addListener('completeReset', this.callback); }, business : function(){ Manager.fireEvent('needReset'); }, callback : function(){ ... }};
Component_4 = { business : function(){ Manager.fireEvent('needBusiness'); }};
Manager = { addListener : function(){ ... }, fireEvent : function(){ ... }};
Component_1 = { construct : function(){ Manager.addListener('needUpdate', this.update); Manager.addListener('needReset', this.reset); }, update : function(){ Manager.fireEvent('completeUpdate'); }, reset : function(){ Manager.fireEvent('completeReset'); }};
Component_2 = { construct : function(){ Manager.addListener('needBusiness', this.business); Manager.addListener('completeUpdate', this.callback); }, business : function(){ Manager.fireEvent('needUpdate'); }, callback : function(){ ... }};
С точки зрения кода Manager — тот же Module.
В нашем случае, часть функций менеджера выполняется jQuery.
Другая часть выполняется одним из компонентов.
Manager «размазало» по коду :)Но дискомофорта из-за этого не испытываем.
Module_2
Component_3Manager
Event
Component_4
Module_1
Component_1
Component_2
Event-driven. Практика
Вызов событий
Генерируем сразу на компоненте.Избавились от посредников.
Module_2
Component_3Manager
Event
Component_4
Module_1
Component_1
Component_2
Event-driven. Практика
Шина.
Непосредственно на компоненте.
Специально созданный объект (proxy).
RequestSender = function( elem ){ this.$element = jQuery(elem); ... }
RequestSender.prototype._getData = function(){ this.$element.trigger('js-waiting-data'); }
Вызов событий
Генерируем сразу на компоненте.Избавились от посредни ков.
Module_2
Component_3Manager
Event
Component_4
Module_1
Component_1
Component_2
Event-driven. Практика
Проблема зоны видимости событий
Разные компоненты могут вызывать один и тот же эвент.
Module_2
Component_3Manager
Event
Component_4
Module_1
Component_1
Component_2
Event-driven. Практика
События привязаны к компонентам.
Некоторые события существуют вне компонентов (один элемент — один эвент — несколько компонентов).
RequestSender = function( elem ){ this.$element = jQuery(elem); } RequestSender.prototype.complete = function(){ this.$element.trigger('js-form-update'); } DynamicForm = function( elem ){ this.$element = jQuery(elem); }
DynamicForm.prototype.update= function(){ this.$element.trigger('js-form-update'); }
Проблема зоны видимости событий
Разные компоненты могут вызывать один и тот же эвент.
Module_2
Component_3Manager
Event
Component_4
Module_1
Component_1
Component_2
Event-driven. Практика
Проблема именования событий
Имена событий — параметризуемые.
Module_2
Component_3Manager
Event
Component_4
Module_1
Component_1
Component_2
Event-driven. Практика
Как быть с дефолтными событиями?
Как быть с событиями конкретных компонентов?
Что делать с общими событиями?
RequestSender = function( elem ){ this.$element = jQuery(elem);
this.requestEvent = this.$element.data('requestEvent'); this.waitingDataEvent = this.$element.data('waitingDataEvent'); this.readyDataEvent = this.$element.data('readyDataEvent'); }
Проблема именования событийModule_2
Component_3Manager
Event
Component_4
Module_1
Component_1
Component_2
Event-driven. Практика
Имена события — параметризуемые.
Кто вызвал событие на компоненте?
Источник события — параметр события.
Module_2
Component_3Manager
Event
Component_4
Module_1
Component_1
Component_2
Event-driven. Практика
Каждому источнику — уникальноесобытие.
Передавать источник события.
this.$element.trigger( this.changeEvent, {'eventSource' : 'filter'} );
Кто вызвал событиена компоненте?
Module_2
Component_3Manager
Event
Component_4
Module_1
Component_1
Component_2
Event-driven. Практика
Источник события — параметр события.
Для кого предназначенособытие?
Источник события — параметр события.
Module_2
Component_3Manager
Event
Component_4
Module_1
Component_1
Component_2
Event-driven. Практика
Получатель — не всегда источник.
Каждому получателю — уникальное событие.
Передавать получателя.
this.$element.trigger( this.readyEvent, {'eventTarget' : this.$resultList});
Для кого предназначенособытие?
Module_2
Component_3Manager
Event
Component_4
Module_1
Component_1
Component_2
Event-driven. Практика
Источник события — параметр события.
Проблемы внутри компонента
Кто кого: метод вызывает событиеили же событие вызывает метод?
Module_2
Component_3Manager
Event
Component_4
Module_1
Component_1
Component_2
Event-driven. Практика
Событие предназначено для связывания компонентов.
Компонент слушает сам себя.
Кто кого: метод вызывает событиеили же событие вызывает метод?
Module_2
Component_3Manager
Event
Component_4
Module_1
Component_1
Component_2
Event-driven. Практика
this._init = function(){ var context = this; this.$element.on('js-clear', function(){ context.clearFields(); }); } ИЛИ this.clearFields = function(){ ... this.$element.trigger('js-clear'); };
Проблемы внутри компонента
Кто кого: метод вызывает событиеили же событие вызывает метод?
Module_2
Component_3Manager
Event
Component_4
Module_1
Component_1
Component_2
Event-driven. Практика
this._init = function(){ var context = this; this.$element.on('js-do-clear', function(){ context.clearFields(); }); } this.clearFields = function(){ ... this.$element.trigger('js-complete-clear'); };
Проблемы внутри компонента
Event-driven. Итоги
Одинаково работают на любых проектах.—
—
—
—
—
—
Меньше зависимостей, больше гибкости.
Лучшая отказоустойстойчивость.
Сложность восприятия.
Большая вероятность появления «мусора».
Необходимость более тщательного проектирования приложения.
Забыть нельзя использовать
Вопросы?
Спасибо!
Антон ВеретенниковИлья Семаков