Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Срабатывание обработчика события там, где он срабатывать не должен (http://www.flasher.ru/forum/showthread.php?t=179280)

Maestro13 11.05.2012 12:42

Срабатывание обработчика события там, где он срабатывать не должен
 
В классе А регистрируем обработчик для события
Код AS3:

private function func():void
{
  mapLoader = new Loader();
  mapLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, mapComplete);
  mapLoader.load(new URLRequest(url));
}
private function mapComplete(e:Event):void
{
 trace("do something");
}

В неком классе В есть обработчик enterFrame и мувиклип:
Код AS3:

private function BEnterFrame(e:Event):void 
{
  trace("начало");
  mc.nextFrame();
  trace("конец");
}

Так вот, вызываем func(), потом вызывается обработчик BEnterFrame. После выполнения mc.nextFrame(); начинает выполняться mapComplete(e:Event), а только потом продолжает выполняться BEnterFrame(e:Event)

Результат получается такой:
trace("начало");
trace("do something");
trace("конец");


Понять не могу, каким это способом nextFrame() генерирует событие Event.COMPLETE у mapLoader.contentLoaderInfo

Добавлено через 1 час 31 минуту
Можно даже все немного упростить. Вот весь код
Код AS3:

package 
{
        import flash.display.Loader;
        import flash.display.MovieClip;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.net.URLRequest;
 
 
        public class Main extends Sprite
        {
                private var loader:Loader;
                private var mc:MovieClip;       
 
                public function Main():void
                {
 
                        trace("entry point");
                        loader = new Loader();
                        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
                        loader.load(new URLRequest("road.swf"));
 
                        mc = new MovieClip();
                        mc.addEventListener(Event.ENTER_FRAME, onEnterFrameListener);       
                }
 
                private function onComplete(e:Event):void
                {
                        trace("onComplete");
                        loader.removeEventListener(Event.COMPLETE, onComplete);
                }
                private function onEnterFrameListener(e:Event):void
                {
                        trace("onEnterFrameListener: start");
                        mc.nextFrame();//prevFrame(); gotoAndStop(); gotoAndPlay();
                        trace("onEnterFrameListener: end");
                }
 
        }
 
}

Результат:
...
onEnterFrameListener: start
onComplete
onEnterFrameListener: end
...

samana 12.05.2012 00:37

А почему вы думаете, что команда mc.nextFrame() вызывает событие onComplete у лоадера? Так как загрузка асинхронная, то просто событие onComplete срабатывает между start и end в ентерФрейме, я так думаю.

elder_Nosferatu 12.05.2012 01:34

Вложений: 1
Для успокоения души советую прикрепить последний пример к fla-файлу как Document Class и воспользоваться во время теста ролика флешовой фишкой [Simulate Download]. Тогда на низких скоростях соединения (настройка скорости имитации соединения - [Download Settings]) вы увидете когда вам в трейс попадет "onComplete"
Вложение 27960

Maestro13 13.05.2012 13:34

elder_Nosferatu, ответ подразумевает, что выполнение скрипта может прерываться. А это противоречит условиям работы платформы. Скрипт не может быть прерван, и не может выполняться параллельно, флеш однопоточен, по крайней мере пока

Добавлено через 7 минут
К томуже, если на место mc.nextFrame(); поставить все что угодно, кроме prevFrame(); gotoAndStop(); или gotoAndPlay(); то все будет вылоняться так, как это должно быть. Тоесть результат ВСЕГДА будет такой:
...
onEnterFrameListener: start
onEnterFrameListener: end
onComplete
...

даже если на место nexFrame поставить
var j:Number=0;
for(var i:int=0;i<100000000;i++)
{
j+=Math.sqrt(i);
}
Этот скрипт выполняется несколько секунд, однако, результат всегда будет правильный.

Из тех соображений что:
1)Выполнение скрипта прерываться не может
2)onComplete вызывается только, если написать функции: nextFrame(); prevFrame(); gotoAndStop() gotoAndPlay();

Я пришел к выводу, что onComplete вызывается из nextFrame();//prevFrame(); gotoAndStop() gotoAndPlay();

Rzer 13.05.2012 14:20

Наверное функция nextFrame включает следующий цикл перерисовки экрана, а Event.COMPLETE вызывается как раз в следующем цикле для загруженных файлов, чтобы избежать ситуации, когда ты подписываешься на это событие, а оно уже сработало.

Maestro13 15.05.2012 23:13

Rzer, а можно поподробнее, или ссылочку какую-нибудь дайте, а то не совсем понятна ваша мысль?

Партизан 16.05.2012 03:10

Ивенты помещаются в стек, загрузка файла началась, соответственно теоретически файл может скачаться за один кадр. Было бы удивительнее если бы Complete сработал прежде EF :)
P.S. Кстати вроде бы с версии 11.2 есть и многопоточность...

Gaen 16.05.2012 04:45

В моем понимании происходит следующее:

1. Вы запускаете загрузку.
2. Вызывается BEnterFrame. В этот момент загрузка завершается и в стек вызовов попадает Event.COMPLETE.
3. Внутри BEnterFrame вызывается смена кадра. В стек попадает продолжение BEnterFrame. Стадия выполнения кода в текущем кадре прекращается.
4. Кадр сменяется, наступает стадия выполнения кода. Выполняется код из стека (точнее очереди) вызовов - сначала отработка события, затем продолжение BEnterFrame.

Более подробно о том, что за стадия выполнения кода, можно прочитать здесь:
http://www.senocular.com/flash/tutor...rofoperations/


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

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