In Flash there is no such thing as run a function asynchronously, you have to do it yourself, unless you want to use Workers (like Vesper said). Workers gives you a separate process. Otherwise, you have to break your calculation into parts. This is how you do it:
Imaging 'trace' is a very heavy operation. It's not, but just to illustrate. This simple for-loop is runned on a frame, and causes a lower framerate, since it's all calculated before the frame actually renders.
for(var i:int = 0; i < 1000; i ++)
{
trace(i); // heavy calculation here
}
So you have to break the calculation into parts, and break it to be able to run the calculation over time.
To do that, you have to create a function which just takes a part of the loop every time:
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);
}
}
This is actually the same function as the simple for-loop in the first code, it also outputs 1000 traces. It is prepared to run in parts, but this isn't async yet. We can now change the function easily, so the function operates over time.
I use the setTimeout
for this. You can also use a ENTER_FRAME
event-listener or the Timer
class for this, but for the sake of this example I try to keep it clear.
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);
}
}
As you can see, I've added a timeBeforeNextRun
parameter. If you run the example, you can see it takes 100 milliseconds before 20 traces are outputted.
If you set it very low, the calculation will be tried to be done very fast, however you cannot gain extra speed just by trying to do more in less time of course. You have to play with the time and amount variables, you can test which one actually gives better performance (or less lag).
// 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);
Hope this helps.
If you want to use a smarter calculation of the time, I found this utility class very helpful, which measures how much time the calculation actually took, and alter the time itself.