05.27Tutorial - Implementing your own CallLater function is AS3 (Flash or Flex)
Hi Everyone,
Although I am not a big fan of the CallLater function in Flex's UIComponent, I must admit that it is sometimes handy. Here is how you can implement your own CallLater function, this code can be incorporated inside of any class, enabling you to add functions that are called after the current thread of execution has been depleted.
DataClass to hold the information
By looking at the members of the Function class, I realized the most elaborate way of using it was through the apply function which takes 2 arguments:
thisArg-- the replacement for the this while inside of the function, essentially deciding to which object the function will belongargArray-- an array containing all the arguments to the function being called
To take advantage of this, we need to store 3 informations for each entry into our queue of functions to be called later, as seen in this class definition:
-
package newcommerce.utils
-
{
-
/**
-
* ...
-
* @author Martin Legris -- http://blog.martinlegris.com
-
*/
-
-
public class CallLaterData
-
{
-
protected var _this:Object;
-
protected var _args:Array;
-
protected var _func:Function;
-
-
public function CallLaterData(func:Function, args:Array, $this:Object)
-
{
-
_this = $this;
-
_args = args;
-
_func = func;
-
}
-
-
public function call():void
-
{
-
_func.apply(_this, _args);
-
}
-
}
-
}
This class stores the 3 informations needed, and implements a call() function which will execute the instruction as we expect it to be.
Implementation
What we need essentially to implement a callLater function is:
- an Array containing the queued items
- a timer to be started when the queue is populated and stopped once the queue has emptied
- and a listener function for the timer pulse, which executes the queued items
- a function to add items into the queue
Please note that the Flex implementation uses "onEnterFrame" event instead of a Timer. I chose a timer because it is more versatile, it can be used in any object, not only display objects.
Here is the code:
-
package newcommerce.utils
-
{
-
import flash.events.TimerEvent;
-
import flash.utils.Timer;
-
-
/**
-
* ...
-
* @author Martin Legris -- http://blog.martinlegris.com
-
*/
-
public class CallLater
-
{
-
protected var _timer:Timer;
-
protected var _calledLater:Array;
-
-
public function CallLater()
-
{
-
_calledLater = [];
-
_timer = new Timer(33, 0);
-
_timer.addEventListener(TimerEvent.TIMER, doTimer);
-
}
-
-
protected function callLater(func:Function, args:Array, $this:Object):void
-
{
-
_calledLater.push(new CallLaterData(func, args, $this));
-
-
if (!_timer.running)
-
{
-
_timer.start();
-
}
-
}
-
-
protected function doTimer(evt:TimerEvent):void
-
{
-
var data:CallLaterData;
-
while (_calledLater.length> 0)
-
{
-
data = _calledLater.shift() as CallLaterData;
-
data.call();
-
}
-
-
if (_calledLater.length == 0)
-
_timer.stop();
-
}
-
}
-
}
That's it folks. If you need assitance, just ask questions below!
Martin

Hi, why did you put 33 milliseconds in timer?
May 28th, 2009 at 2:03 am
@Denis
Usually, I use a frameRate of 30 frames per second for my flash projects, so this 33 milliseconds value would match this frameRate. However, it is not important (to my understanding), I could have put 10, or 100.. If the value is too high, then it will simply take longer to execute. Remember that Flash is single-threaded, so as long as you use a timer, the calls WILL be executed after the current “thread” of execution.
May 28th, 2009 at 8:16 am
Why not use:
Application.application.callLater(func, args);
December 14th, 2009 at 12:55 pm
@Tr cause “Application” doesn’t exist outside of Flex! And cause it is nice to understand how things work.
December 14th, 2009 at 1:14 pm
[...] only be executed once, not twice. I showed how to implement your own callLater function in this post. For this example, I won’t go there. There is no [...]
December 15th, 2009 at 12:21 pm