异步运行AS3功能

时间:2012-11-22 07:20:30

标签: actionscript-3 asynchronous flash-cs5.5 document-class

我在网上学习一些教程时遇到了一些麻烦,因此我在这里问。 (使用ActionScript 3,Adobe AIR和Flash Professional CS5.5)

我的AS3文档类中有一个非常繁重的函数,我需要异步运行,因此它不会停止MovieClip本身的代码(不要问我为什么,它只需要那样。)

所以,简单地说,如何异步运行此文档类函数(StartNow)?代码可以放在文档类或movieclip上,我不在乎哪里。这似乎是一个相对简单和普遍的做法,但我所有的研究都没有挖掘任何东西。

谢谢!

2 个答案:

答案 0 :(得分:4)

如果您的目标是Flash Player 11.4,则可以为Worker对象分配如此繁重的功能。我没有FP11,最终制作了一个程序生成器,每次迭代总共超过300秒。我不得不使用基于状态的方法,与输入框架侦听器配对。在我看来,整个复杂的生成过程被分成逻辑块,这些逻辑块足够小,可以在合理的时间内完成,并且具有跟踪当前生成阶段的变量。因此,当另一个帧称为生成函数时,它从该变量读取最后完成的步骤,使用其数据集执行一个额外步骤,存储新值并退出该帧。这样,它不是一个纯粹的异步过程,而是一个伪多任务方法,如果你的SWF滞后函数是可拆分的,这可能适合你。

答案 1 :(得分:2)

在Flash中没有异步运行函数的事情,你必须自己动手,除非你想使用Workers(比如Vesper所说)。工人为您提供单独的流程。否则,您必须将计算分解为多个部分。你就是这样做的:

成像'追踪'是一项非常繁重的操作。它不是,而只是为了说明。这个简单的for循环在一个帧上运行,并导致较低的帧速率,因为它是在帧实际渲染之前计算的。

for(var i:int = 0; i < 1000; i ++)
{
   trace(i); // heavy calculation here
}

因此,您必须将计算分解为多个部分,并将其分解以便能够随时间运行计算

要做到这一点,你必须创建一个函数,每次只占用循环的一部分:

calculatePart(0, 1000, 20);

function calculatePart(startIndex:int, endIndex:int, amountPerRun:int)
{
    for(var i:int = startIndex; (i < startIndex + amountPerRun) || (i < endIndex); i ++)
    {
        trace(i); // heavy calculation here
    }
    if (i < endIndex)
    {
        calculatePart(i, endIndex, amountPerRun);
    }
}

这实际上与第一个代码中的简单for循环功能相同,它还输出1000条跟踪。它准备运行部分,但这不是异步。我们现在可以轻松更改功能,因此功能会随着时间的推移而运行。 我为此使用了setTimeout。您也可以使用ENTER_FRAME事件监听器或Timer类来实现此目的,但为了这个示例,我尝试保持清晰。

calculatePart(0, 1000, 20, 100);

function calculatePart(startIndex:int, endIndex:int, amountPerRun:int, timeBeforeNextRun:Number)
{
    for(var i:int = startIndex; (i < startIndex + amountPerRun) && (i < endIndex); i ++)
    {
        trace(i); // heavy calculation here
    }
    if (i < endIndex)
    {
        setTimeout(calculatePart, timeBeforeNextRun, i, endIndex, amountPerRun, timeBeforeNextRun);
    }
}

如您所见,我添加了timeBeforeNextRun参数。如果运行该示例,则可以看到在输出20条迹线之前需要100毫秒。

如果你把它设置得很低,计算将会非常快地进行,但是你不能仅仅通过在更短的时间内做更多的事情来获得额外的速度。你必须使用时间和数量变量,你可以测试哪一个实际上提供了更好的性能(或更少的滞后)。

 // more time between a run, less calculations per run
 calculatePart(0, 1000, 30, 10);

 // more calculations per run, more time between a run
 calculatePart(0, 1000, 100, 30);

希望这会有所帮助。

如果你想更聪明地计算时间,我发现this实用程序类非常有帮助,它可以测量计算实际花费的时间,并改变时间本身。