Friday, June 25th, 2010

How Custom Events Will Save Us All

Category: JavaScript

<>p>

I am a big fan of both Andrew Dupont, and custom events.

In his presentation he goes through some very nice use cases. Some are cross cutting (e.g. the fact that you can unit test, or debug, or … so much easier) and some are specific such as:

Scripty2 animation heartbeat

javascript
< view plain text >
  1. // keep the heartbeat going
  2. setTimeout(function() {
  3.   document.fire("effect:heartbeat");
  4. }, 0);
  5.  
  6. // listen in
  7. document.observe("effect:heartbeat", advanceEffectByOneFrame);
  8.  
  9. // allows for nice debugging
  10. document.observe("keydown", function(event) {
  11.   if (event.keyCode === Event.KEY_RIGHT) {
  12.     document.fire("effect:heartbeat");
  13.   }
  14. });

Another nice example is how you can start using the new and cool EventSource while retrofitting the functionality for browsers who don’t implement the new standard:

javascript
< view plain text >
  1. // new browsers
  2. var eventSource = $('event_source');
  3. eventSource.observe('server-sent-event-name', function(event) {
  4.   document.fire('data:received', event.data);
  5. });
  6.  
  7. // old browsers
  8. new Ajax.Request('/legacy/polling', {
  9.   onComplete: function(request) {
  10.     document.fire('data:received', request.responseJSON);
  11.   }
  12. });
  13.  
  14. // observer works for both
  15. $(document).observe('data:received', function(event) {
  16.   doStuff(event.memo);
  17. });

And, there are many more great examples in the slides.

How have you been using custom events?

Related Content:

Posted by Dion Almaer at 6:02 am
19 Comments

++++-
4 rating from 1 votes

19 Comments »

Comments feed TrackBack URI

That’s really cool! Although this is a very very useful approach I doubt that people are using it in some large scale web apps.

Here’s what Nicholas Zakas says about scalable javascript architecture – based, of course, on custom events! Nicholas C. Zakas — Scalable JavaScript Application Architecture

Than, inspired by him, I wrote a quick guide trough jQuery’s approach – Event driven programming with jQuery

Comment by stoimen — June 25, 2010

Welcome to ActionScript2 technology! It’s great seeing JavaScript finally catching up to ActionScript in some regards. I miss custom events dearly.

Comment by gmariani — June 25, 2010

Mootools has this built in for it’s Class implementation. Custom events are being heavily used for most of the MT classes and the classes on the Forge.

Comment by ariehg — June 25, 2010

We’re using custom events to drive our entire application. It’s a single-page application, inspired by the techniques John Nunemaker used on harmonyapp.com. There’s a demo video of our app here: http://screenr.com/zpK

I think attaching handlers directly to DOM elements is the Old World way of adding interaction. Using custom events allows your code to be much more organized and modular. I’m not used to that in JavaScript.

Comment by kylefox — June 25, 2010

We actually need Erlang in the webbrowser. I only can say “Stay Tuned”, as I’m working on something for last year.

Comment by movax — June 25, 2010

Actually I never work without custom events. Even if I don’t have them in a project for some reason, I create a class which will implement it.
If i have YUI, I always use the EventProvider util which makes easy to add the compatibilities of custom events to my modules.

Comment by Ajnasz — June 25, 2010

The yayQuery team was really glad to have Andrew debut this talk at TXJS a few weeks ago — I’m glad to see it getting some attention beyond the audience of a couple hundred developers we had there :)

Comment by rdmey — June 25, 2010

This is really just a description of the Active Events design pattern from O2 Software Process/Architecture, which I described more than a year ago, which again is built on top of the ideas from SmallTalk and CAB (Composite Application Blocks)
.
For those interested, the O2 Process/Architecture/Design-Patterns are described in great details at http://legosoftwareprocess.org – Yes, I did get an email from Lego’s attorneys … ;)
.
Now the fact that it’s been mentioned before, for more than 40 years in fact too, doesn’t invalidate the authors great ideas. Though it is something to think about for devs in general …

Comment by ThomasHansen — June 25, 2010

Just before I read this I started building our key event architecture based around….custom events (and Prototype custom events at that!). I danced around a variety of function callback solutions first before realizing that re-writing escape() (or whatever) for each module was ridiculous. Bubble-up is the new OO!

Comment by AngusC — June 25, 2010

Custom events are the best way to handle the single and double click condition race

Comment by emehrkay — June 26, 2010

What’s wrong with this picture?

Discussion of LOD for code that augments external objects — and host objects at that — seems self-contradictory.

Problems< with augmenting host objects have been mentioned. Andrew Dupont seldom posts on c.l.js, however these issues have even appeared in articles).

An “event notification system” that doesn’t break the registry is a great idea and the first known, published article explaining how to do that was not that of Dean Edwards’; it was my own, published in January, 2008 (latest version on Github). I published it in response to a claim by a Google interviewer (on his blog) that I had copied his eval-based event system and presented it in the interview, to him. Nope – I didn’t do that at all!

Comment by dhtmlkitchen — June 27, 2010

Whoops, sorry about the anomalous “<". By the way, I never know if I should make entities for those or not. Test:


Not entity: <
Entity: <

Comment by dhtmlkitchen — June 27, 2010

Custom events are a powerful and yet underestimated message passing tool, but they have their warts too: first of all there are no private events, so any code part can bind to an event and e.g. hook into the private methods of your class.

The second danger I see that your code gets too loosely coupled and therefore difficult to read, a line like document.fire(“foobar”) doesn’t tell you which code parts are currently subscribed to that event and in which order their event handlers will be executed – you actually have to run the code to find this out.

With callbacks the execution scope and sequence are far more obvious. Custom events give you cheap debugging but also demands a lot of debugging messages for the reasons above.

My verdict is that custom events are a powerful tool, but certainly not a vademecum for scalable javascript applications.

Comment by znarfdwarf — June 27, 2010

“first of all there are no private events,”

So you haven’t figured out how to implement private events, is that right?

I see bits what I’ve written about in my article, mangled and misapplied. Making private events is not all that hard.

Comment by dhtmlkitchen — June 27, 2010

@dhtmlkitchen, I’m sorry that I did not see your post regarding event dispatch. If I had then I would have given you some credit in my post. I also failed to see that the Prototype library had this covered pretty well.

The important thing is that this subject is getting some attention.

Comment by deanedwards — June 27, 2010

Hi all. I couldn’t find any chance to read all of the comments but I’ll read next visit.

In the observer implementation I coded for the new framework I’ve been working on, each event subject is an object containing subscribers. Example usage;

var onread = new Subject();
onread.subscribe(function..
onread.emit()

To make subject objects easier to manage (create/remove/fire), I coded a wrapper class named SubjectSet:

this.events = new SubjectSet();
this.events.create(“read”);
this.events.fire(“read”); // -> this.events.subjects.read.emit()

I’m not a fan of OOP but this implementation have been working seamlessly for me. Currently my framework is not documented because of my schedule, but you can check out its source code and tests:

http://github.com/azer/roka/tree/master/src/async/observer.js
http://github.com/azer/roka/tree/master/test/suites/async/observer.js

any ideas and suggestions are welcome.

Comment by azer — June 28, 2010

I think using custom events in that manner is not a good practice, because it tightens (hence messes up) application logic with view logic. Notifications (or as you call them here “custom events”) distribution mechanism should be decoupled from UI events and be orchestrated in a different location, for example in some application bus. The rationale here is simple – view events propagate through trees, notifications usually propagate through a line (unless you exercise PAC approach in the app logic). Take a look into MVC in Flash – there you also have a notion of events (usually originated in views) and notifications (usually originated in controller) separate.

Comment by SergeyIlinsky — June 28, 2010

Relying on the DOM’s event’s is a very bad idea.
.
1) Event handler execution order is not consistent cross-browser (IE is random, everyone else is first-in-first-out). http://dl.dropbox.com/u/513327/event_order.html
.
2) Some browsers may have problems firing events (I know there is a Prototype ticket about this and NetFront, PS3′s browser).
.
3) Using DOM events for custom object events clutters up the handlers for elements. For example Prototype binds all custom events through the “dataavailable” event (plus the “filterchange” event for IE). This means if you have 100 handlers and only two are the “one:uwant” it has to check through 100 handlers for those 2. Not to mention that if your element changes opacity in IE it will trigger the “filterchange” event every time a child is updated. Yikes !
http://dl.dropbox.com/u/513327/dom_events_fail.html
.
@Garrett (dhtmlkitchen) – Using setTimeout() breaks the synchronous awesomeness of the event system and also directs the debugger to the wrong line number when it reports the error.

Comment by jdalton — June 28, 2010

For me since MVC was invented, in Xerox PARC ages ago, it was clear that it was the right thing to do.

Javascript is late bound so it can take further advantage of them (making events not only for elements).

We use custom events (so custom reactions) for @airflowing in a daily basis. All that behaves at the DOM uses this. It’s the thing that allows us to maintain things loosely coupled and objects ignoring everything that doesn’t matter to them.

That’s what makes it a scalable and elegant solution. Actually, events are saving us since forever.

Comment by sebastianconcept — June 30, 2010

Leave a comment

You must be logged in to post a comment.