我有一个类,我必须按特定顺序运行几种方法。所以,我创建了一种链,每个链都在最后一句中调用下一个链(有时会调用,有时会调度事件):
internal function a(evt:SwapEvent):void { //started from custom event
...
b();
}
private function b():void {
...
bTimer = new Timer(bTime*1000,1);
bTimer.addEventListener(TimerEvent.TIMER, bEnd);
bTimer.start();
}
private function bEnd(evt:TimerEvent):void {
bTimer.removeEventListener(TimerEvent.TIMER, bEnd);
bTimer = null;
c();
}
private function c():void {
...
dispatchEvent(new CustomEvents(CustomEvents.NEXT_FRAME,1));
}
....
private function g():void {
// tell the second class the sequence finished
}
问题是在某个时刻,在到达最后一个方法之前,我需要再次运行一个子序列,假设从函数c()到e()。并且它会导致功能之间延迟增加(我有2个定时器)的问题
我想解决方案是这样的:
a();
b();
...
if (some condition) {
c();
...
e();
}
...
f();
g();
但据我所知,Flash Player不会进行同步执行。即,它不会等到方法a()完成执行b()
关于清洁和防弹实施的任何想法/建议?此应用程序将在24x7无限循环中运行
答案 0 :(得分:4)
正确阅读您的代码后,是的,您是对的。 b()在达到该行代码时执行。
我可能想要创建一个要执行的方法队列。执行一个,检查在帧需要更新之前是否有时间执行另一个,然后重复。您可以随时将新命令插入队列,因此b()可以在队列中插入endB()。
http://www.dpdk.nl/opensource/running-tasks-in-order-with-a-task-based-sequence-manager和http://as3.casalib.org/docs/org_casalib_time_Sequence.html的音序器都应该做你需要的。前者可能有点矫枉过正,因为看起来你需要为每个任务创建单独的类,这可能有点过多的开销。另一方面,条件任务看起来就像你需要的那样。后者更简单,因为您可以指定要执行的方法。但是,似乎没有内置的方式来调整任务,但这可能就像创建有条件地添加任务的任务一样简单。
了解条件如何运作可能会有所帮助。
其他要点:
在AS中,尾调用效率不高。将其视为每次调用方法时向堆栈添加更多内容。一旦该方法返回(即使您没有明确使用return
),该方法也会从堆栈中被淘汰,之前调用的方法将继续执行。因此尾部调用越多,堆栈越大,清理越多。
一旦你开始执行代码,玩家就会挂起,直到代码完全运行并且执行已经返回给玩家。在玩家杀死你的脚本之前你有大约15秒的执行限制,所以你必须在无休止地执行代码时考虑到这一点。解决方案是执行一些代码然后等到下一帧执行更多。
您不必重新创建计时器,您可以将它们创建为实例变量,然后只需调用start。计时器将返回执行到播放器(如果没有更多的方法调用)。
一个有点简化的版本,但我相信你能得到它。
ADDENDUM:我认为您应该查看命令模式(http://en.wikipedia.org/wiki/Command_pattern)。您可以存储要执行的命令数组(同步或异步),当一个命令返回或调度complete事件时,执行下一个命令。我认为你可以创建一个简单的命令模式实现来完成你所需要的,而不需要我之前提到过的序列发生器的所有开销,但总是很好的了解其他人是如何做到的。
答案 1 :(得分:3)
有许多库在AS3中提供顺序执行。通常它们用于执行动画,因此它们通常会偏向于此。
例如,Twease
和Tweener
将允许您执行顺序操作以及通用动画操作。
另一个特别好的测序库作为asapframework ...的一部分包含在内,它有一个名为ActionQueue
的类,您可以在其中添加TimedAction
项。关于TimedAction
&的好事ActionQueue
是添加撤消方法和参数的功能,如果您需要向后运行序列。
使用音序器比手动设置大量定时器简单得多。
答案 2 :(得分:1)
我真的不明白你的问题。 actionscript一般是同步的(除了一些可以异步执行的AIR函数),但是一个定时器是异步的,因为你的代码不会暂停并等待定时器完成,然后再继续主线程。
如果希望方法仅在完成计时器后执行,请使用timer事件TIMER_COMPLETE事件侦听器。