Tuesday, March 31st, 2009

The differences between Callbacks and Events

Category: JavaScript

Dean Edwards has a subtle piece on callbacks vs. events where he calls out the issue of libraries that support custom events dying out when one custom event dies.

First, Dean sets the stage:


  1. document.addEventListener("DOMContentLoaded", function() {
  2.   console.log("Init: 1");
  3.   DOES_NOT_EXIST++; // this will throw an error
  4. }, false);
  6. document.addEventListener("DOMContentLoaded", function() {
  7.   console.log("Init: 2");
  8. }, false);

Which outputs the correct:

Init: 1

Error: DOES_NOT_EXIST is not defined

Init: 2

However, with jQuery and Dojo, using their style of event handling apparently dies out too early:

Init: 1

Error: DOES_NOT_EXIST is not defined

And YUI swallow the error so you just see the two inits.

Prototype seems to win this one, but other frameworks support this in different ways (e.g. Dojo with pub/sub, and connect).

Posted by Dion Almaer at 6:03 am

4.3 rating from 25 votes


Comments feed TrackBack URI

When are you guys going to give us wider columns ? This is getting ridiculous, I’m sick of scrolling to read code.

Comment by MikaMTB31 — March 31, 2009

I think it’s fair for a framework to behave like that. The alternatives would be:

1.) Wrap each listener into a try … catch block and throw the error after all other listeners have finished. This is really hard to debug because in most browser’s you loose the context of the exception.

2.) Call the listeners asynchronously with a timeout. This absolutely kills performance.

3.) A combination of both. Wrap the listeners in a try … catch block and only if an exception occurs call the remaining listeners asynchronously. The exception can be rethrown immediately after calling setTimeout.

Out of these options I think only the last one seems to make some sense to me. But considering the benefit it’s probably add just another level of unjustified additional complexity.

Comment by fjakobs — March 31, 2009

There is a good debate about this article over on the jquery dev mailing list with Dean Edwards, John Resig, and others


Comment by howardrauscher — March 31, 2009

I banged my head against this problem for quite a while using Dojo a couple years ago. This presents a real problem for creating modular systems – you add one new component to a page, and it can bring down anything that executes after it.

As fjakobs mentions, the hard part about this is handling errors in an intelligent way. I was never able to hack together anything that would work reliably, but hopefully someone will come up with a solution.

Comment by BarelyFitz — March 31, 2009

@BarelyFitz, I provide a solution to the problem – wrap the callback system in a real event. It works.

Comment by deanedwards — March 31, 2009

Wouldn’t it be possible, theoretically, to do this?

// loop through listeners and :
try {
// call listener
} catch(e) {

Comment by warfangle — March 31, 2009

@warfangle: That would be possible, but it is not desireable because you would be throwing away any exceptions, so it would be impossible to debug problems that occur.

@deanedwards: Great to see a solution! A couple years ago I tried to solve this using try/catch and storing each exception in an array – ha, that totally didn’t work (a little knowledge can be a dangerous thing!)

Here’s hoping the frameworks (other than Prototype which got it right) will be updated to behave this way.

Comment by BarelyFitz — April 1, 2009

Incidentally, the example provided fails in MooTools 1.2.1 as well.

Comment by minkeytorture — April 2, 2009

@MikaMTB31: I agree. In Firefox, I’ve added these 2 lines to my userContent.css file:

div#wrapper div#pagebody div#maincontent {min-width:744px !important;}
div#wrapper div#pagebody div#maincontent div.entry div.syntax_hilite {min-width: 727px !important}

Or checkout the “Stylish” Add-on to do the same thing: https://addons.mozilla.org/en-US/firefox/addon/2108

Comment by NOSLOW — April 3, 2009

Leave a comment

You must be logged in to post a comment.