AS3:按顺序运行方法

时间:2010-10-22 20:31:01

标签: actionscript-3 asynchronous

我有一个类,我必须按特定顺序运行几种方法。所以,我创建了一种链,每个链都在最后一句中调用下一个链(有时会调用,有时会调度事件):

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无限循环中运行

提前致谢,

3 个答案:

答案 0 :(得分:4)

正确阅读您的代码后,是的,您是对的。 b()在达到该行代码时执行。

我可能想要创建一个要执行的方法队列。执行一个,检查在帧需要更新之前是否有时间执行另一个,然后重复。您可以随时将新命令插入队列,因此b()可以在队列中插入endB()。

http://www.dpdk.nl/opensource/running-tasks-in-order-with-a-task-based-sequence-managerhttp://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中提供顺序执行。通常它们用于执行动画,因此它们通常会偏向于此。

例如,TweaseTweener将允许您执行顺序操作以及通用动画操作。

另一个特别好的测序库作为asapframework ...的一部分包含在内,它有一个名为ActionQueue的类,您可以在其中添加TimedAction项。关于TimedAction&的好事ActionQueue是添加撤消方法和参数的功能,如果您需要向后运行序列。

使用音序器比手动设置大量定时器简单得多。

答案 2 :(得分:1)

我真的不明白你的问题。 actionscript一般是同步的(除了一些可以异步执行的AIR函数),但是一个定时器是异步的,因为你的代码不会暂停并等待定时器完成,然后再继续主线程。

如果希望方法仅在完成计时器后执行,请使用timer事件TIMER_COMPLETE事件侦听器。