42 Строки Кода Для Выхода Из Подвешенного Состояния

Вы знаете, как это бывает: большой проект долго проектируют, долго пишут, иногда мучаются и в конце концов сдаются.

Проходит месяц очередной «горячей отладки», а потом наступает благоговейное молчание.

Мы ничего не услышали от клиента.

И не потому, что он разорился благодаря вашим усилиям; Счета за телефон у него не оплачены, а интернет давно отключен, нет) У него все работает как обычно.

Но однажды.

Верно! Мыло прибыло» ваша программа не работает "(с)баш), телефоны раскаляются докрасна, а юристы нервно перечитывают то, что положили в раздел "гарантийное обслуживание".

У нас была точно такая же ситуация.

Мы делали довольно весомый проект, суть которого можно было описать так (вкратце, конечно): есть разный контент (клиентская база, маркетинговая база, база данных подключений и т. д., т. п.

и т. п.

) и разные способы его представления (виджет, всплывающее окно, модальное окно и т. д.).

То есть с нашей стороны была подготовлена платформа (API доступа к данным, визуализация, вся экосистема, как модно говорить (хотя я не знаю, что это значит, но звучит очень круто)) для того, чтобы разработчики заказчика могли записать данные своих контроллеров и просто «поместить» их в файл в указанное место, после чего вы с радостью увидите, как появляется новенький виджет со списком текущих котировок по какому-то хитроумному индексу.

И, как я уже сказал, все шло хорошо.

Мы провели несколько «мастер-классов», все показали, все рассказали, выпили пива и начали веселиться.

Уже без нас.

Пока все не сломалось.

Правильно: «все» и «сломалось».

В какой-то момент приложение просто начало зависать.

Настолько, что закрыть вкладку браузера невозможно.

Более-менее опытный веб-разработчик сразу скажет, что у вас где-то застрял шлейф, ребята.

И он будет прав, и что.

Но прежде чем перейти к этим 42 строкам кода, я просто напомню, что когда у вас есть приложение с кучей всяких вкусностей внутри, то лучший способ организовать связь между ними — через внутренние события.

А у наших на момент сдачи проекта их было около сотни, а когда начались проблемы, их число увеличилось еще на пару десятков.

И, как вы уже догадались, застрял именно контроллер событий.

На пальцах: событие А вызывает событие Б, а событие Б вызывает событие С, а оно, в свою очередь, снова вызывает событие А.

Та-да-м, встречайте цикл! Наш обработчик событий был невероятно простым и содержался в файле из 44 строк кода.

Однако он не знал, как сделать очень важную вещь — проверить, не попал ли он в петлю.

Мне не пришлось много думать о том, чтобы выпить, и решение было найдено довольно быстро.

Хорошо это или плохо, зависит только от вас.

Опишу только основную идею.

Единственный способ проверить, «кто» стал причиной цепочки событий (в нашем примере — нахождение A, B и C) — это проверить стек.

Чтобы получить стек нужно просто «кинуть» ошибку.

Остается проблема — как «пометить» место вызова события, ведь в стеке должно быть что-то, что помогло бы распознать всю цепочку ранее запущенных событий? Одним из решений этой проблемы являются именованные функции-обертки, в имени которых хранится вся информация о предыдущих событиях.

Ничего не понимаю? Написал, перечитал и тоже не понял.

Легче смотреть код .

По сути, теперь, если вы сделаете это (событие A вызывает B, B вызывает C, а C снова вызывает A):

  
  
   

var safeevents = new SafeEvents(); safeevents.bind('A', function () { safeevents.trigger('B'); }); safeevents.bind('B', function () { safeevents.trigger('C'); }); safeevents.bind('C', function () { safeevents.trigger('A'); }); safeevents.trigger('A');

На этот раз приложение не уйдет в подвешенное состояние, а выдаст исключение «Неперехваченная ошибка: событие [A] вызвало само себя.

Полная цепочка: А, Б, С».

Прибыль.

Теперь разработчику не нужно делать три лишних перекура, чтобы разобраться, что происходит на самом деле — все видно из сообщения в консоли.

Асинхронные вызовы немного сложнее.

Для них, к сожалению, нужно выполнить дополнительное действие.

Но он настолько мал, что вряд ли станет большой проблемой.



var safeevents = new SafeEvents(); safeevents.bind('A', function () { safeevents.trigger('B'); }); safeevents.bind('B', function () { safeevents.trigger('C'); }); safeevents.bind('C', function () { /* * Use method "safely" to wrap your async methods and create safe callback. */ setTimeout(safeevents.safely(function () { safeevents.trigger('A'); }), 10); }); safeevents.trigger('A');

Обратите внимание на функцию обратного вызова в таймере.

Добавляем «обертку» для передачи данных о предыдущих событиях в асинхронных вызовах.

И снова в консоли увидим: «Uncaught Error: Event [A] вызвало само себя.

Полная цепочка: А, Б, С».

Конечно, не всегда нужно делать это и нагло выбрасывать исключение.

Гораздо лучше незаметно сообщить, куда следует записывать данные в журнал или отправить уведомление админу.

Почему можно поставить свой обработчик на случай «зацикливания» и получить все необходимые данные.



var safeevents = new SafeEvents(); safeevents.bind('A', function () { safeevents.trigger('B'); }); safeevents.bind('B', function () { safeevents.trigger('C'); }); safeevents.bind('C', function () { safeevents.trigger('A'); }); safeevents.bind(safeevents.onloop, function (e, chain, last_event, stack) { console.log('Error message: ' + e); console.log('Full chain of events: ' + chain.join(', ')); console.log('Last event (generated loop): ' + last_event); console.log('Error stack: ' + stack); }); safeevents.trigger('A');

Теперь наше приложение вообще не будет прерываться, но цикл будет успешно предотвращен.

В общем, переписав наш простейший обработчик событий и получив дополнительно 42 строки кода, мы решили очень редкую, но довольно неприятную проблему с зацикливанием событий.

Кто знает (не знаю), возможно, и вам это будет полезно.

Все здесь .

Счастья, добра и электричества в ваши дома.

Теги: #JavaScript #node.js #events #цикл событий #emmiter #Разработка веб-сайтов #JavaScript #node.js

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.