Tuesday, March 31st, 2009
The differences between Callbacks and Events
<>p>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:
-
-
document.addEventListener("DOMContentLoaded", function() {
-
console.log("Init: 1");
-
DOES_NOT_EXIST++; // this will throw an error
-
}, false);
-
-
document.addEventListener("DOMContentLoaded", function() {
-
console.log("Init: 2");
-
}, 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).








When are you guys going to give us wider columns ? This is getting ridiculous, I’m sick of scrolling to read code.
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.
There is a good debate about this article over on the jquery dev mailing list with Dean Edwards, John Resig, and others
http://groups.google.com/group/jquery-dev/browse_thread/thread/2a14c2da6bcbb5f/c257fa0900c97457?lnk=gst&q=callback+event#c257fa0900c97457
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.
@BarelyFitz, I provide a solution to the problem – wrap the callback system in a real event. It works.
Wouldn’t it be possible, theoretically, to do this?
// loop through listeners and :
try {
// call listener
} catch(e) {
continue;
}
@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.
Incidentally, the example provided fails in MooTools 1.2.1 as well.
@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