Introducing the AsyncLoop class
Out of my recent work, I’m especially proud of and excited about the AsyncLoop class. It’s a serious performance enhancer that takes heavy processes and spreads them out over time, preventing stalls and possible lockups. I originally wrote it to deal with a for loop that contained a complex process and iterated 1000 times. Needless to say, the beach ball made an extended stay each time the loop ran. After implementing AsyncLoop, the beach ball disappeared and animations played smooth throughout.
AsyncLoop works around a timer limit. The developer sets the maximum number of milliseconds to loop through the process function. Once the timer exceeds that limit, it carries over to the next frame and repeats. The loop can be ended a number of ways, providing great flexibility. A limit can be placed on the loop count, mimicking common for loop usage. The loop can return the AsyncLoopAction.BREAK constant. When using that method, AsyncLoopAction.CONTINUE is used to tell the loop to continue to the next tick. Each loop provides analytics, keeping track of its duration, loop count, and frame count. Here are two ways you can use it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | // new AsyncLoop(callback:Function, countLimit:int = -1, timerLimit:int = 20); var loop:AsyncLoop = new AsyncLoop(tick, 1000); loop.addEventListener(Event.OPEN, loopOpenHandler); loop.addEventListener(Event.CHANGE, loopChangeHandler); loop.addEventListener(Event.COMPLETE, loopCompleteHandler); loop.start(); function tick():void { // heavy process } function loopOpenHandler(event:Event):void { // loop started } function loopChangeHandler(event:Event):void { // loop carries over to next frame trace(loop.duration); // incomplete loop running time trace(loop.currentCount); // number of callback calls } function loopCompleteHandler(event:Event):void { // loop complete trace(loop.duration); // completed loop duration trace(loop.frameCount); // frames needed to complete } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | var loop:AsyncLoop = new AsyncLoop(tick); loop.start(); stage.addEventListener(MouseEvent.CLICK, clickHandler); stage.addEventListener(MouseEvent.DOUBLE_CLICK, doubleClickHandler); function tick():String { // heavy process if (loopShouldEnd) { return AsyncLoopAction.BREAK; } return AsyncLoopAction.CONTINUE; } function clickHandler(event:MouseEvent):void { if (loop.running) { loop.pause(); } else { loop.start(); } } function doubleClickHandler(event:MouseEvent):void { loop.cancel(); } |
I’m really happy with the class and how far it has come since its original form as fLoop. As always, the source code is on GitHub, so take it and run! If you find it useful, feel free to share how you used it, or simply let me know what you think.


