views:

773

answers:

2

I have been trying to understand the way ActionScript's events are implemented, but I'm stuck.

I know that AS is single threaded, which means that only one event handler will be executing at a time, and also means that handlers will be executed in a deterministic order*.

For example, consider the following code:

1: var x = {executed: false};
2: foo.addEventListener("execute", function(){ x.executed = true; });
3: foo.dispatchEvent(new Event("execute"));
4: assert(x.executed);

If ActionScript was multi-threaded, it would be possible that the assertion on line 4 could fail sometimes and succeed others.

But since AS is not multi-threaded, it stands to reason that the assertion will either always fail² or always succeed³. Or, in other words, events will be handled in a deterministic way.

So, is this assumption (that events hare handled deterministically) correct? Does Adobe provide any definitive documentation on the matter?

Note: I am only concerned here with events dispatched by dispatchEvent – I realize that "externally dispatched" events (network traffic, user input, timers ticking, etc) behave differently.


*: with the exception, of course, for events triggered by nondeterministic things like user input or network traffic.
²: it would always fail if, for example, if the event handling algorithm was: "push new events onto a stack, then continuously pop the top event off the stack, execute it until it terminates, then go on to the next event".
³: it would always succeed if events dispatched by dispatchEvent were handled as soon as they were dispatched.

A: 

line 4 will ALWAYS execute before the event handler, so executed will always assert as false. After the function has finished, the handler will execute.

You're point 2 is the correct way to look at it.

CookieOfFortune
Unfortunately, by experimentation, that's not true :(
David Wolever
@CookieOfFortune. I'm afraid you're wrong. Event dispatching / handling is not necessarily asynchronous.
Juan Pablo Califano
+4  A: 

Unless I'm misunderstanding -- in which case I do apologize! -- I have to disagree with the others: you need only test the code you've submitted to see the value of x.executed traces true every time.

For example, if, in place of your foo object, you were to substitute an IEventDispatcher (in this case I do so implicitly, with my app object and its creationComplete handler), you'd see:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="onCreationComplete()">

    <mx:Script>
     <![CDATA[

      private function onCreationComplete():void
      {
       var x = {executed: false};
       addEventListener("execute", function() { x.executed = true; });
       trace(x.executed); // false
       dispatchEvent(new Event("execute"));
       trace(x.executed); // true
      }

     ]]>
    </mx:Script>

</mx:WindowedApplication>

Of course, there are ways of controlling event-handling order (using the priority argument of addEventListener), and various phases of event propagation for objects on the display list (e.g., capturing, targeting, bubbling -- see the Flex docs for detailed information, here and here), but in this kind of situation, events are indeed handled essentially inline and in priority order. According to the docs:

Flex registers event listeners in the order in which the addEventListener() methods are called. Flex then calls the listener functions when the event occurs in the order in which they were registered. However, if you register some event listeners inline and some with the addEventListener() method, the order in which the listeners are called for a single event can be unpredictable.

Hope that helps!

Christian Nunciato
Thanks for the answer. I had suspected this, but I didn't want to trust my intuition without some confirmation.
David Wolever