我在没有for循环的情况下一遍又一遍地让事情发生有困难。看一看这个:
package {
    import flash.display.Sprite;
    import flash.events.Event;
    public class Main extends Sprite {
        public function Main() {
            addEventListener("done", caller);
            caller();            
        }
        public function caller(e:Event = null):void {
            trace("hello!");
            dispatchEvent(new Event("done"));
        }
    }
}唱这会给您带来一个“错误#2094:事件分派递归溢出”。真快啊。它将显示事件分派程序和调用者()在它们的内部被调用,嵌套直到错误发生。
我想做的是:“当调用者()完成时,再次调用它”not:“在调用完成之前调用调用者()”
现在,在人们开始建议使用计时器来猜测它将花费多长时间或使用ENTER_FRAME之前,这个调用者()将没有任何图形数据,也不会连接到Sprite,并且它完成调用所需的时间可能因调用不同而有很大差异。我真的在寻找一种方法来运行它后,它已经完全完成。
谢谢你的帮助。
谢谢你的答复。我使用计时器,但仍然可以溢出太多的电话和太短的计时器间隔。因此,我简化并尝试创建一个基于for循环类的事件(一个类似for循环的类,但是使用事件来避免占用所有的资源)解决方案是调用函数,在它完成时调用计时器;在定时器完成时,再次调用函数并将它们相互弹回。基本上:
call function
wait
call function
wait etc.即使定时器设置为0,并冻结swf直到调用所有函数,函数在再次运行之前都将完成。
试试看:
package {
import flash.display.Sprite;
public class Efl extends Sprite { // the main class
    public function Efl() {
        // make four functions...
        function init (o:Object):void { // akin to the first part of the for loop
            o.value = 0;
        }
        function condition(o:Object):Boolean { // like the condition portion of the for loop
            if (o.value <= 100) {
                return (true);
            } else {
                return (false);
            }
        }
        function next(o:Object):void { // the increment part of a for loop
            o.value++;
        }
        function statements(o:Object):void { // the body of the for loop
            trace(o.value);
        }
        // put the four functions in one new EventForLoop
        var test1:EventForLoop = new EventForLoop(init, condition, next, statements, 1); // delay is 1 ms
        test1.start(); // set it into motion
        // do it again all in one line - not pretty but it works
        var test2:EventForLoop = new EventForLoop(
            function (o:Object):void { o.value = 0; },
            function (o:Object):Boolean { if (o.value <= 50) return (true); else return (false); },
            function (o:Object):void { o.value++ },
            function (o:Object):void { trace("> " + o.value) },
            20); // delay in 100ms
        test2.start(); // start it up
        // if you try this out, the two will run intertwined since the delays are different.
    }
} 
}下面是运行循环的类:
package {
import flash.events.EventDispatcher;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.utils.Timer;
public class EventForLoop extends EventDispatcher {
    // functions to call when simulating the for loop
    private var initializer:Function; // is run once at the start of the loop
    private var condition:Function; // returns boolean to tell the loop to continue or not
    private var step:Function; // the function that runs after the loop is complete
    private var statements:Function; // the actual body of the loop
    private var timeout:Timer; // the timer to avaoid overflows
    private var operator:Object = new Object(); // this is an object to hold and pass values across all the sub loop functions. it is the parameter passed to all four functions
    // some event constants
    static const NEXT:String = new String("EFLNext"); 
    static const DONE:String = new String("EFLDone");
    // constructor just loads vars and sets up timer
    public function EventForLoop (init:Function, cond:Function, stepper:Function, stat:Function, delay:Number = 0) {
        initializer = init;
        condition = cond;
        step = stepper;
        statements = stat;
        timeout = new Timer(delay, 1);
    }
    // the mail loop function...
    private function next(e:Event = null):void {
        // Try this and the lone afte the loop:
        // trace ("start statements");
        if (condition.call(null, operator)) { // if the condition is still true...
            statements.call(null, operator); // do the body statements of the loop
            step.call(null, operator); // increment
            dispatchEvent(new Event(EventForLoop.NEXT)); // dispatch the event so that thw wait can start
        } else { // condition returns false??
            dispatchEvent(new Event(EventForLoop.DONE)); // tell the event dispatcher the loop is done
            removeEventListener(EventForLoop.NEXT, wait); // stop event listeners
            timeout.removeEventListener(TimerEvent.TIMER_COMPLETE, next); 
        }
        // trace ("finish statements\n");
        // this line and the one before the if() will show that the functcion ends before starting again, even if the Timer wait 0ms
    }
    // very simple function that waits and ten triggers the  loop again
    private function wait(e:Event):void {
        timeout.reset();
        timeout.start();
    }
    // metod used to set the loop running
    public function start():void {
        initializer.call(null, operator); // use the initioalizer to set the operator Object
        addEventListener(EventForLoop.NEXT, wait); // when the loops done, wait
        timeout.addEventListener(TimerEvent.TIMER_COMPLETE, next); // when done waiting, loop again
        next(); //do the first loop
    }
} 
}发布于 2009-07-25 17:27:52
您可能需要尝试使用flash.utils.setTimeout()。把它放在caller()的底部,让它为自己设置一个超时。如果您给它一个非常小的超时间隔,它将异步递归下一次Flash获得机会。
或者,一个ENTER_FRAME事件将或多或少地做同样的事情(除了极高的框架)。Flash将延迟下一个帧的渲染,直到一个帧上的所有处理逻辑都完成。此外,Flash是单线程的,因此可以保证您的函数的两个副本永远不会同时运行。
https://stackoverflow.com/questions/1181324
复制相似问题