Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 29.04.2012, 19:37
Mirror13 вне форума Посмотреть профиль Отправить личное сообщение для Mirror13 Найти все сообщения от Mirror13
  № 1  
Ответить с цитированием
Mirror13
 
Аватар для Mirror13

Регистрация: May 2010
Адрес: Ногинск
Сообщений: 56
По умолчанию Обработка ошибок при асинхронном выполнении кода

Я задавал этот вопрос на двух ресурсах, но он до сих пор без ответа. Но, тем не менее, вопрос интересный. Изначально он касался JavaScript'а, но в целом эта тема так же актуальна и относительно ActionScript'а, я не раз задумывался над этим.

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

Я долго и упорно искал что-то по теме обработки ошибок в JS при асинхронном выполнении, но находил только что-то вроде этого:
Код AS1/AS2:
try {
    helloWorld();
}
catch (e) {
    alert(e.message);
}
 
function helloWorld() {
    throw new Error('Hello world!');
}
Когда-то я и относительно AS искал такую информацию - результат был настолько же не впечатляющим.

Есть ли хорошие статьи по поводу обработки ошибок при асинхронном выполнении, особенно в JS или AS3? Может быть, существуют специфические паттерны или малоизвестные возможности этих языков?

Старый 29.04.2012, 19:41
Bgg вне форума Посмотреть профиль Отправить личное сообщение для Bgg Найти все сообщения от Bgg
  № 2  
Ответить с цитированием
Bgg
 
Аватар для Bgg

Регистрация: Jan 2009
Адрес: Петерсбург
Сообщений: 1,882
События
Код AS3:
loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);

Старый 29.04.2012, 20:31
Mirror13 вне форума Посмотреть профиль Отправить личное сообщение для Mirror13 Найти все сообщения от Mirror13
  № 3  
Ответить с цитированием
Mirror13
 
Аватар для Mirror13

Регистрация: May 2010
Адрес: Ногинск
Сообщений: 56
Да, это базовое понятие программирования на AS. Но, по сути дела, это тот же коллбэк, который вызывается по событию. Но что делать потом?

Если бы событие могло всплывать по всему стеку вызовов, и генерироваться любым объектом, можно было бы кинуть кастомное событие. Но, насколько мне известно, это не так.


Последний раз редактировалось Mirror13; 29.04.2012 в 20:33.
Старый 29.04.2012, 21:32
Wolsh вне форума Посмотреть профиль Отправить личное сообщение для Wolsh Найти все сообщения от Wolsh
  № 4  
Ответить с цитированием
Wolsh
Нуб нубам
 
Аватар для Wolsh

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Приведите пример асинхронного стека.
try/catch/finally используется только в синхронном коде, незачем обвинять его в непригодности там, где он и не подписывался помогать.
В асинхронном коде используются События, и другого инструмента, кроме естественного, нет.
Асинхронные ошибки могут произойти после вызова асинхронных операций вроде загрузки, коих немного. Обычно (не уверен, что всегда, только потому, что не все еще во флэше перепробовал)) исполнители таких операций обещают сообщать об ошибках процесса, если это вообще возможно (если плеер вообще получает какую-то информацию от внешней среды, с которой взаимодействует в процессе асинхронной операции). Приведите конкретный пример, посмотрим.
__________________
Reality.getBounds(this);

Старый 29.04.2012, 22:04
Mirror13 вне форума Посмотреть профиль Отправить личное сообщение для Mirror13 Найти все сообщения от Mirror13
  № 5  
Ответить с цитированием
Mirror13
 
Аватар для Mirror13

Регистрация: May 2010
Адрес: Ногинск
Сообщений: 56
Я не совсем это имел в виду. Ясное дело, что try/catch не работает с асинхронными вызовами. Вопрос в том, есть ли способы сделать механизм для обработки ошибок при асинхронных вызовах, который был бы так же удобен, как исключения при синхронных.

Как пример можно привести обертку для запросов на сервер. Допустим, там есть метод:
Код AS3:
public function getData(resource:String, onSuccess:Function, onError:Function):void
{
    _applyRequest(resource, URLRequestMethod.GET, onSuccess, onError);
}
Внутри метода _applyRequest есть такой код:
Код AS3:
loader.addEventListener(IOErrorEvent.IO_ERROR, onLoadError);
loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onLoadError);
И, соответственно:
Код AS3:
function onLoadError(e:ErrorEvent):void {
    e.target.removeEventListener(e.type, arguments.callee);
    if (onError !== null)
        onError(e);
    else
        throw 'Network error';
}
Вот если бы можно было избавиться от протягивания коллбэка onError, а как-то через весь стек передать сигнал. В синхронном случае это исключение. В случае экранных объектов можно использовать dispatchEvent. А можно ли что-нибудь придумать в этом случае?

Старый 29.04.2012, 23:03
Wolsh вне форума Посмотреть профиль Отправить личное сообщение для Wolsh Найти все сообщения от Wolsh
  № 6  
Ответить с цитированием
Wolsh
Нуб нубам
 
Аватар для Wolsh

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Цитата:
Вопрос в том, есть ли способы сделать механизм для обработки ошибок при асинхронных вызовах, который был бы так же удобен, как исключения при синхронных.
В смысле предвидел ошибки до их появления?
Как может асинхронный быть таким же, как синхронный? Помните картинку популярную с кубиками, на которых написаны буквы "А","П","Ж" и "О", и "пока не соберешь слово СЧАСТЬЕ, домой не пойдешь"?
Цитата:
Вот если бы можно было избавиться от протягивания коллбэка onError, а как-то через весь стек передать сигнал.
Кому передать? Уже нет никакого стека. Он кончился, остался в прошлом. Избавиться от протягивания — пожалуйста, просто подпишитесь на события. Работайте с Объектом, а не с функцией. AS3 это ООП-язык. Вы просите Объект загрузить данные. Объект участливо предоставляет Вам события. Зачем создавать свою систему поставок через единый коннектор-метод, непонятно. Вы никак не обработаете ошибку до ее появления. Вам придется резать код на методы-обработчики, как бы ни хотелось писать функцию-простыню в 1000 строк. Асинхронная ошибка это Событие по самой своей сути. То, как поступают с ней в языке — естественное природное поведение, и нарушить законы времени не удастся. Код не будет сам стоять и ждать, что ответит getData. Для этого надо поставить закрывающую скобку и написать новый блок, который запустится, когда хозяин getData отрапортует об исходе операции.
__________________
Reality.getBounds(this);

Старый 29.04.2012, 23:13
Mirror13 вне форума Посмотреть профиль Отправить личное сообщение для Mirror13 Найти все сообщения от Mirror13
  № 7  
Ответить с цитированием
Mirror13
 
Аватар для Mirror13

Регистрация: May 2010
Адрес: Ногинск
Сообщений: 56
Ясно.

Я так понимаю, что для использования событий нужно, чтобы класс наследовался от EventDispatcher'а. В этом случае можно будет делать примерно так:
Код AS3:
serverDataInstance.addEventListener(ServerData.ERROR_EVENT, onError);
И, соответственно:
Код AS3:
function onLoadError(e:ErrorEvent):void {
    e.target.removeEventListener(e.type, arguments.callee);
    dispatchEvent(new Event(ERROR_EVENT));
}
Но всплыть на несколько уровней вверх это событие не сможет, и перехватить его можно будет только на том уровне, где был создан serverDataInstance, я правильно понимаю?

Старый 29.04.2012, 23:45
Wolsh вне форума Посмотреть профиль Отправить личное сообщение для Wolsh Найти все сообщения от Wolsh
  № 8  
Ответить с цитированием
Wolsh
Нуб нубам
 
Аватар для Wolsh

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Да. Создаем объект и перед вызовом сомнительного метода подписываемся на событие об ошибке.
А зачем выше? Чтобы обрабатывать все в Едином Центре Ошибок в Мейне? То есть Мейну надо будет знать детали реализации своих неуравновешенных детишек?)) Честно сказать, тут я не советчик — никогда не пытался строить архитектуру таким образом. Мне кажется, что с ошибкой в результате выполнения метода должен разбираться тот, кто этот метод вызвал. Но если не так, то придется на этот раз ему отсылать событие наверх, дескать "шеф, усё пропало!" Знаю, знаю. Опять протягивание, опять многоступенчатая передача. Но на деле мне кажется это не так страшно, как кажется))))) Я бы даже сказал, что здесь больше гибкости и осмысленности, но нет, у меня недостаточно опыта в построении систем с синхронными ошибками, чтобы сравнивать.
Цитата:
нужно, чтобы класс наследовался от EventDispatcher'а.
Есть еще композиция. Но обычно да, если хочется кастомные события то проще наследоваться (если действительно кастомные, то есть собственный класс событий, а не строковый тип).
Цитата:
Но всплыть на несколько уровней вверх это событие не сможет
Вроде есть самопальные реализации всплытия для недисплейных цепочек, поищите, я сам не интересовался настолько подробно.
__________________
Reality.getBounds(this);

Старый 30.04.2012, 00:26
Mirror13 вне форума Посмотреть профиль Отправить личное сообщение для Mirror13 Найти все сообщения от Mirror13
  № 9  
Ответить с цитированием
Mirror13
 
Аватар для Mirror13

Регистрация: May 2010
Адрес: Ногинск
Сообщений: 56
Спасибо за информацию )
Цитата:
А зачем выше? Чтобы обрабатывать все в Едином Центре Ошибок в Мейне?
Вполне может пригодиться для фатальных ошибок, при которых дальше работать не имеет смысла. К примеру, приложение требует постоянной связи с сервером, а ее нет - нужно уведомить пользователя, что все пропало, и остановить работу.

Но, видимо, не судьба ) Вряд ли самостоятельно реализовывать всплытие по всем уровням лучше, чем вызывать нужные коллбэки или передавать по всем уровням событие.

Цитата:
Есть еще композиция. Но обычно да, если хочется кастомные события то проще наследоваться (если действительно кастомные, то есть собственный класс событий, а не строковый тип).
Я не большой знаток этого паттерна, но я так понимаю, он не совсем подойдет для общего случая.

Композиция - если я правильно понимаю, это иерархия объектов с одинаковым интерфейсом, в которых как раз реализована передача сообщений от нижнего уровне наверх. Как DOM в HTML или дерево экранных объектов во Flash'е. А мне было интересно, что делать в общем случае.

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

Старый 30.04.2012, 00:38
ChuwY вне форума Посмотреть профиль Отправить личное сообщение для ChuwY Посетить домашнюю страницу ChuwY Найти все сообщения от ChuwY
  № 10  
Ответить с цитированием
ChuwY
 
Аватар для ChuwY

Регистрация: Nov 2009
Адрес: Тула / Москва
Сообщений: 734
Отправить сообщение для ChuwY с помощью ICQ Отправить сообщение для ChuwY с помощью Skype™
Вы путаете с паттерном "компоновщик".
Композиция это отношение "включает в себя", противопостовляющееся наследованию, выражающему "является".

Добавлено через 1 минуту
Кстати, реализовать свое всплытие не сложно и вполне себе кошерно пользоваться этим.
(реализовывал, но пользоваться не приходилось, если честно. просто случаев не представлялось, хотя есть идеи)
__________________
9 из 10 голосов в моей голове сказали наркотикам "НЕТ"
Мои ачивки: художник-паразит.

Создать новую тему Ответ Часовой пояс GMT +4, время: 09:17.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 09:17.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.