Javascript.RU

Устойчивость системы обработчиков к ошибкам

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

Если какой-нибудь обработчик содержит ошибку, то, генерируя исключение, он ломает цикл вызова остальных обработчиков текущего элемента/события.

Получается, что обработчики зависят друг от друга. Есть различные способы, как этого избежать.

Можно завернуть вызов каждого обработчика в try .. catch. Тогда исключение будет поймано.

Что делать дальше?

Есть варианты.. Например, библиотека Yahoo UI хранит последнее пойманное исключение в специальной переменной lastError. А фреймворк Mochikit собирает все пойманные исключения в errors.

В коде ниже проиллюстрирован подход из Mochikit:

function commonHandle(event) {
  event = fixEvent(event)
  handlers = this.events[event.type]
  
  // (1)
  var errors = []
 
  for ( var g in handlers ) {
    try {
      var ret =  handlers[g].call(this, event)
      if ( ret === false ) {
        event.preventDefault()
        event.stopPropagation()
      }
    } catch(e) {
      // (2)
      errors.push(e)
    }
  }
  
  // (3)
  if (errors.length == 1) {
      throw errors[0]
  } else if (errors.length > 1) {
      var e = new Error("Multiple errors thrown in handling 'sig', see errors property");
      e.errors = errors
      throw e
  }  
}
  1. Инициализуется массив errors для исключений
  2. Все исключения - добавляем в массив, при этом не прерывая цепочку обработчиков.
  3. Если была только одна ошибка - кидаем ее дальше. Иначе делаем общий объект Error со списком ошибок в свойстве errors и кидаем его.

Каждый вызов обработчика можно завернуть в setTimeout.
Пожалуй, это самый простой способ.

// вместо
handlers[g].call(this, event)
// поставить
setTimeout(function() { handlers[g].call(..) }, 0)

При этом - да, обработчики будут вызваны независимо. Но к моменту, когда сработает setTimeout - событие будет уже "мертво", нельзя будет ни вызвать preventDefault, ни отменить всплытие.

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

Поэтому, увы, этот способ никак не годится.

Этот подход описан Dean Edwards в статье Callbacks and Events

Он заключается в том, что каждое событие заворачивается не в setTimeout, а в dispatchEvent (fireEvent для IE).

Таким образом, события вызываются в независимых потоках выполнения и инициируют ошибки независимо.

Есть несколько вариантов, как сделать систему событий устойчивой к ошибкам.
Жизнеспособны - первый подход (YUI/Mochikit) и последний (Dean).

Их можно с успехом использовать на практике.


Автор: tenshi, дата: 10 февраля, 2010 - 02:19
#permalink

Автор: vaporasleep (не зарегистрирован), дата: 15 ноября, 2022 - 12:25
#permalink

Мы ценим, что вы нашли время, чтобы поделиться своими мыслями. Я прочитал ряд статей на ту же тему! Однако, в отличие от других статей, которые я читал, ваша произвела на меня глубокое впечатление. Я надеюсь, что вы и дальше будете публиковать полезные посты, подобные этому, чтобы все могли их прочитать. krunker


Автор: Гость (не зарегистрирован), дата: 14 апреля, 2011 - 07:28
#permalink

Я оборачиваю вызов каждого обработчика в try, и в catch делаю setTimeout с повторной генерацией оригинальной ошибки. В результате, и выполнение обработчиков не прерывается, и ошибка будет показана родная, то есть будет показана и строка в которой возникла ошибка и прочая инфа.

// Фрагмент общего обработчика для MISE
// только для msie
        // this -- нод на котором происходит событие
        handlers = this[eventsPropertyName][event.type]
        // ... пропущена инициализация fixEvent
        // копирование недостающих свойств в event msie
        for (var propertyName in fixEvent) {
            if (!event[propertyName]) {
                event[propertyName] = fixEvent[propertyName]
            };
        };

        // для всех обработчиков повешенных на текущий нод для текущего типа события
        for (var i in handlers) {
            try {
                ret = handlers[i].call(this, event);
            } catch (err) {
                // собственно вот:
                setTimeout(
                    (function (err) {
                        return function () { throw err }
                    })(err), 0
                );
            };
            if (ret === false) {
               returnValue = false;
            };
        };
        return returnValue;

Спасибо вам за статьи. Сам бы только много позже обратил бы внимание на такой момент


Автор: tenshi, дата: 14 июля, 2011 - 20:02
#permalink

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

а вообще, забавно - сначала отказываемся от нативных событий эмулируя их через свой объект, а потом для вызова каждого обработчика генерируем нативное событие, чтобы он не ронял остальные хD не проще ли сразу честно вешать обработчики на события?

.ня


Автор: Гость (не зарегистрирован), дата: 15 декабря, 2011 - 15:12
#permalink

не проще ли сразу честно вешать обработчики на события?

Если бы евенты во всех браузерах были одинаковые, тогда и не было б необходимости отказываться от нативных событий эмулируя их через свой объект


Автор: zenitchik (не зарегистрирован), дата: 13 августа, 2012 - 12:16
#permalink

Не вижу проблемы в том, что при падении одного обработчика, прекращается выполнение других.
Если в каком-то обработчике ошибка - значит приложение в целом неработоспособно, и выполнять остальные обработчики нет смысла.


Автор: Гость (не зарегистрирован), дата: 13 июня, 2018 - 20:39
#permalink

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


Автор: Hank (не зарегистрирован), дата: 16 июня, 2020 - 22:10
#permalink

thanks for sharing this!! tyler fence companies


Автор: Гость (не зарегистрирован), дата: 16 июня, 2020 - 22:25
#permalink

Автор: Гость (не зарегистрирован), дата: 16 июня, 2020 - 22:28
#permalink

this is great, thanks for sharing granite countertops spokane


Автор: francesca (не зарегистрирован), дата: 1 сентября, 2020 - 04:10
#permalink

Thank you for sharing, I find the various alternatives that the collection of tutorials always brings us very useful and very useful. ancrea catalogos


Автор: Гость (не зарегистрирован), дата: 22 декабря, 2020 - 22:42
#permalink

I never really did get into the whole BDSM thing. I thought that it was a bit too wild for my taste. I prefer a more conventional sexual experience. I don’t like to experiment that much because I don’t need that kind of adrenaline in my life. I like it safe and secure and available now in mobile legends pc. I don’t want anything to awaken in me that I would regret. I have a very addictive personality and if I try BDSM, I might get addicted and that would totally hamstring my dating life in roblox download.


Автор: Гость (не зарегистрирован), дата: 18 января, 2021 - 10:11
#permalink

slope unblockedWow, this is very interesting reading. I found a lot of things which I need. Great job on this content. This is very interesting reading. Great job on this content. I like itcookie clicker


Автор: john lead (не зарегистрирован), дата: 2 ноября, 2021 - 07:25
#permalink

This weblog is fantastic. I really like studying your articles. Keep up the good writings! You realize, a lot of persons are hunting around for this info, you can help them greatly.

strata painting Cessnock


Автор: Ken Han (не зарегистрирован), дата: 3 июня, 2022 - 02:51
#permalink

You are definitely right. This article is very informative and helpful. | nycdemolitioncontractor.com


Автор: Гость (не зарегистрирован), дата: 16 апреля, 2022 - 00:21
#permalink

Автор: Ufa1688 (не зарегистрирован), дата: 14 июня, 2022 - 12:30
#permalink

Israel withdrew ufa1688 from Gaza in 2005 but, ufabet เข้า สู่ระบบ with the help of Egypt, clamps 1688.com down on the borders of the ทางเข้า Ufa 1688 enclave now governed by แทงบอลออนไลน์ Hamas Islamists. Dream Gaming Palestinian Big gamingauthorities have limited self-rule ลิงค์รับทรัพย์ in the West Bank บาคาร่าwhich is dotted หวยออนไลน์with Israeli settlements.


Автор: mytom2, дата: 12 июля, 2022 - 17:54
#permalink

friday night funkin has become a popular activity that is done on fridays. This is because it's not just a night to have fun, but also one to get rid of stress and anxiety.
The other reason for this trend is because friday nights are usually free from work obligations, which means that people can be more creative and have more fun than usual.
You should also join fnaf, the best horror game out there!


Автор: antiguans2000, дата: 3 августа, 2022 - 18:46
#permalink

The first time you press (starting the loop), the spaces are removed.
See: www.app1.findit.com/About/xdfthmrvicsgghu


Автор: poppy playtime (не зарегистрирован), дата: 4 августа, 2022 - 06:53
#permalink

Thank you for your post. I have read through several similar topics! However, your article gave me a very special impression, unlike other articles. I hope you continue to have valuable articles like this or more to share with everyone! poppy playtime


Автор: Bryan Burch (не зарегистрирован), дата: 10 октября, 2022 - 11:16
#permalink

word hurdle is a sport with simple rules that makes it accessible to players of all ages. You may jump right into the action without any pregame warmups.


Автор: Гость (не зарегистрирован), дата: 11 октября, 2022 - 12:22
#permalink

I read a lot about related stuff! Contrary to other articles I have read, Your article is really engaging, providing me with a lot of valuable information. I hope you will continue to write great blog posts like this for everyone to read.
redactle game


Отправить комментарий

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
5 + 2 =
Введите результат. Например, для 1+3, введите 4.
 
Текущий раздел
Поиск по сайту
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Последние комментарии
Последние темы на форуме
Forum