We’ve been doing a fair amount of interviewing for an open dev spot at work, and I came up with a question that I felt would help me get a sense of where a given candidate was at, whether or not he/she knew the answer.
“Why can’t you dispatch an event from a static method?”
Technically, that should probably be something like, “Why can’t you successfully listen to an event dispatched from a static method”, but the point of the question is to get a feel for how deeply the candidate has looked into or thought about how events work. Or, failing that, how well they can think about it on the spot.
My answer is that a static method is not associated with an object instance, and therefore can not participate in the Display List chain, which the event model is based on – so, no propagation path, no capture phase or bubble phase, and definitely no target phase.
Incidentally, I came up with this question after trying to dispatch an event from a static method…
After thinking about it some more, I realized that this question represents the extent of my knowledge of ActionScript 3′s event model. Like, okay, that’s probably a correct answer but I can’t provide any insight on exceptions to this rule, or any work that has been done to allow a developer to dispatch events from static methods, or anything at all beyond my simple answer (which is really pretty obvious if you have a basic understanding of events, but maybe you’ve just never thought about it).
Here are some examples of other things I don’t know about, regarding the event model:
- Why is there a capture phase? Why would you use it? What makes it computationally expensive (according to Adobe documentation)? Why can you only use either the capture phase or the target/bubble phases (unless you use two event listeners)?
- Is there some other way to dispatch events so that data-only relationships can be event-based?
- Is there a way for a static method to dispatch an event that can be listened for?
That bit about the capture phase being computationally expensive is killing me. WHY??!! I mean, wouldn’t it be computationally less expensive to handle an event in the capture phase and then stop propagation?
After some light research, I feel far less knowledgeable, in spite of actually knowing more.
I started here, with a post about Robert Penner’s AS3 signals, and then moved to a couple posts by Penner critiquing and learning about events in AS3 (1, 2, 3).
From there I moved on to the specification behind the event model – it’s called DOM Level 3 Events. The fact I’d never even heard of this probably says a lot about how much I don’t really know about events.
Then, there’s this post by Darren Schall, which is specific to Flex, but highlights the EventPriority class, which I was not aware of. Not really germaine to the particular problem that is bugging me (why does the capture phase exist, when would it be used, why is it expensive), but interesting in that setting up default event listeners is a really useful thing to know about.
UPDATE: Had some interesting conversation about the capture phase last night at the Austin Flex User Group (which, like this blog, is a treasure trove of people who are a lot smarter than me). No one else really had a good answer as to why you would ever use the capture phase – much less why it is any more expensive to use than the bubble phase, but:
1) Someone asked if I had done any tests to determine if the capture phase actually is more expensive than the bubble phase.
2) A group of us (and some beer) worked our way loudly to a couple of fairly esoteric situations where you might want to know that an event has occurred, but prevent all registered listeners from hearing about it. So, you’d catch the event in the capture phase, run whatever logic you want to run, and then stop propagation.
3) I also struck on the idea of catching an event during the capture phase, modifying it, and then dispatching a clone. Presumably after un-registering the capture phase event listener.
I could see #2 and #3 being potentially useful in a situation where you had to mash your own code against some compiled code that you didn’t have any control of. But, I’m pretty obsessed about this, now, and I want to hear someone who knows what they’re talking about give an answer.
UPDATE: My friend Jason pointed me to this question on StackOverflow. It’s about JavaScript, which is based on the same spec as the event model for ActionScript. There’s an interesting and enlightening comment by El Yobo:
Focus/blur events don’t bubble, but can be delegated at a higher level during the capture phase – quirksmode.org/blog/archives/2008/04/delegating_the.html – El Yobo
So – there’s some practical use of the capture phase.
In the meantime, I’m trying to put together some meaningful tests to see if the capture phase really is more expensive than the bubble phase, in AS. This is not my strongest suit, and I may be approaching this completely incorrectly.
Test #1: Create 30,000 event listeners on a particular event, and time how long it takes them to all fire. Do once using the bubbling phase, and once using the capture phase.
For the first version of this test, each event handler evaluates whether it is the first or last to fire. If it is the first, it writes the time as milliseconds to a textfield labeled ‘Start Time’; if it is the last, it writes the time as milliseconds to a textfield labeled ‘End Time’, and then writes the difference to a textfield labeled ‘Total Time’.
So, 28,000 of the 30,000 listeners are doing nothing more than running the conditionals and seeing that they have nothing to do other than update a counter value.
I ran the test a few times, closing and re-publishing the test SWF in between each test, and got the following:
Bubble phase: 321 ms; Capture phase 333 ms
Bubble phase: 323 ms; Capture phase 324 ms
Bubble phase: 326 ms; Capture phase 323 ms
Bubble phase: 324 ms; Capture phase 324 ms
Bubble phase: 321 ms; Capture phase 322 ms
I ran the same test at 12 fps and at 60 fps, to see if I could get a noticeable variation that way, but didn’t see any modification of the results.
Next version of this test will be for each listener to draw or move something on the stage.