Антон Веретенников и Илья Семаков. Презентация

30
Антон Веретенников Илья Семаков «ПЕРЕХОД ОТ КОЛЛБЕКОВ К СОБЫТИЯМ»

Transcript of Антон Веретенников и Илья Семаков. Презентация

Page 1: Антон Веретенников и Илья Семаков. Презентация

Антон ВеретенниковИлья Семаков

«ПЕРЕХОД ОТ КОЛЛБЕКОВК СОБЫТИЯМ»

Page 2: Антон Веретенников и Илья Семаков. Презентация

Public API

Frontend BackendAJAX

разработать frontend-часть для нового проекта заказчика

Задача:

Page 3: Антон Веретенников и Илья Семаков. Презентация

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

Page 4: Антон Веретенников и Илья Семаков. Презентация

разработать frontend-часть для нового проекта заказчика

Задача:

Пути решения

Callback

Page 5: Антон Веретенников и Илья Семаков. Презентация

разработать frontend-часть для нового проекта заказчика

Задача:

Event-driven

Пути решения

Page 6: Антон Веретенников и Илья Семаков. Презентация

разработать frontend-часть для нового проекта заказчика

Задача:

Callback Event-driven

?

Пути решения

Page 7: Антон Веретенников и Илья Семаков. Презентация

Component_1 = {  update : function( callback ) { callback() },  reset : function( callback ){ callback() }};

Component_2 = {  business : function(){   Component_1.update(this.callback);  },  callback : function(){ ... }};

Callback

Сначала все выглядит вот так

Page 8: Антон Веретенников и Илья Семаков. Презентация

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

Появляются новые требования

Page 9: Антон Веретенников и Илья Семаков. Презентация

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

... и ещё

Page 10: Антон Веретенников и Илья Семаков. Презентация

Callback

... а в итоге получаем

Page 11: Антон Веретенников и Илья Семаков. Презентация

Callback

Хорошо работают на несложных проектах.—

— Слабая гибкость из-за постоянно возрастающих зависимостей.

Page 12: Антон Веретенников и Илья Семаков. Презентация

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Теория

Page 13: Антон Веретенников и Илья Семаков. Презентация

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(){ ... }};

Page 14: Антон Веретенников и Илья Семаков. Презентация

С точки зрения кода Manager — тот же Module.

В нашем случае, часть функций менеджера выполняется jQuery.

Другая часть выполняется одним из компонентов.

Manager «размазало» по коду :)Но дискомофорта из-за этого не испытываем.

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

Page 15: Антон Веретенников и Илья Семаков. Презентация

Вызов событий

Генерируем сразу на компоненте.Избавились от посредников.

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

Шина.

Непосредственно на компоненте.

Специально созданный объект (proxy).

Page 16: Антон Веретенников и Илья Семаков. Презентация

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. Практика

Page 17: Антон Веретенников и Илья Семаков. Презентация

Проблема зоны видимости событий

Разные компоненты могут вызывать один и тот же эвент.

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

События привязаны к компонентам.

Некоторые события существуют вне компонентов (один элемент — один эвент — несколько компонентов).

Page 18: Антон Веретенников и Илья Семаков. Презентация

  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. Практика

Page 19: Антон Веретенников и Илья Семаков. Презентация

Проблема именования событий

Имена событий — параметризуемые.

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

Как быть с дефолтными событиями?

Как быть с событиями конкретных компонентов?

Что делать с общими событиями?

Page 20: Антон Веретенников и Илья Семаков. Презентация

  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. Практика

Имена события — параметризуемые.

Page 21: Антон Веретенников и Илья Семаков. Презентация

Кто вызвал событие на компоненте?

Источник события — параметр события.

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

Каждому источнику — уникальноесобытие.

Передавать источник события.

Page 22: Антон Веретенников и Илья Семаков. Презентация

  this.$element.trigger(    this.changeEvent,     {'eventSource' : 'filter'}  );

Кто вызвал событиена компоненте?

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

Источник события — параметр события.

Page 23: Антон Веретенников и Илья Семаков. Презентация

Для кого предназначенособытие?

Источник события — параметр события.

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

Получатель — не всегда источник.

Каждому получателю — уникальное событие.

Передавать получателя.

Page 24: Антон Веретенников и Илья Семаков. Презентация

this.$element.trigger(    this.readyEvent,     {'eventTarget' : this.$resultList});

Для кого предназначенособытие?

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

Источник события — параметр события.

Page 25: Антон Веретенников и Илья Семаков. Презентация

Проблемы внутри компонента

Кто кого: метод вызывает событиеили же событие вызывает метод?

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

Событие предназначено для связывания компонентов.

Компонент слушает сам себя.

Page 26: Антон Веретенников и Илья Семаков. Презентация

Кто кого: метод вызывает событиеили же событие вызывает метод?

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');  };

Проблемы внутри компонента

Page 27: Антон Веретенников и Илья Семаков. Презентация

Кто кого: метод вызывает событиеили же событие вызывает метод?

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');  };

Проблемы внутри компонента

Page 28: Антон Веретенников и Илья Семаков. Презентация

Event-driven. Итоги

Одинаково работают на любых проектах.—

Меньше зависимостей, больше гибкости.

Лучшая отказоустойстойчивость.

Сложность восприятия.

Большая вероятность появления «мусора».

Необходимость более тщательного проектирования приложения.

Page 29: Антон Веретенников и Илья Семаков. Презентация

Забыть нельзя использовать

Page 30: Антон Веретенников и Илья Семаков. Презентация

Вопросы?

Спасибо!

Антон ВеретенниковИлья Семаков