21 nested callbacks
March 27, 2013<br>21 nested callbacks
About 21 months ago, before I even knew what a callback was, I<br>built my first webpage. In honor of its 21 nested callbacks, I think it's about<br>time I finally take a second look at it.
At the time I had a perhaps cliche habit of doodling in my<br>notebook during humanities classes and family road trips. One particular<br>summer road trip yielded a collection of triangles that I thought looked pretty<br>cool. I decided that a worthy mid-summer endeavour would be to reproduce it<br>digitally. I also thought that would make me extremely cool on Tumblr.
I began by asking CS major friends if they could point me in the right<br>direction. The canned responses I received can be summarized as<br>"Google it." Subtext: "If you can't figure it out from there, you're<br>incompetent."
"I'm trying to make a triangle on my webpage...but Google doesn't seem to<br>give me any good results."
"No, Google 'CSS triangle.' See? It's simple."
"Sorry...what does CSS have to do with triangles?"
The chat logs usually come to an abrupt end at this point, or "CSS is simply how<br>you style your HTML."
(I gathered from these exchanges that programmers have a perpetual competition<br>to see who can claim the most things as 'simple.')
I left each conversation feeling extraordinarily incompetent.<br>Nevertheless I discovered how to make a triangle shape with a div (what's<br>that stand for?) and a few lines of CSS and found a few sites that had cool<br>color-changing effects that I could replicate for my triangle art.
I'm sure you're curious now what I could've possibly conjured up.
Well, here's a glimpse of the HTML:
id="row1"><br>class="btri"><br>class="tri"><br>class="tri"><br>class="tri"><br>class="emp"><br>class="tri"><br>class="tri">
id="row2"><br>class="tri"><br>class="tri"><br>class="tri"><br>class="tri"><br>class="tri">
...
I am sad to report that this goes on for another 165 lines and that the<br>accompanying JavaScript is just as geometric--spoiler: it's a parallelogram.
I learned that there was this thing (library?) called jQuery and that I could<br>use this 'API' thing called 'animate' to change my triangles' various properties<br>gradually. I found that if I called $('#something').animate({ 'opacity': '0' })<br>once, it would make one triangle disappear. In my head it felt logical<br>that if I wanted my 20 rows of triangles to disappear one by one, I had to write<br>that same line 20 times.
I also 'imported' jQuery by copying and pasting the contents of the library to the<br>top of my JavaScript file. I had seen it in a separate file on others' webpages,<br>but I decided to keep all my JavaScript in one file for no particularly good<br>reason.
If I wanted to lie to myself, I could say that I chose the most optimal way to<br>code: in the hard fashion.
$(".disappear").click(function(){<br>$("#row20").animate({ "opacity": "0" },<br>100,<br>function(){$("#row19").animate({ "opacity": "0" },<br>100,<br>function(){$("#row18").animate({ "opacity": "0" },<br>100,<br>function(){$("#row17").animate({ "opacity": "0" },<br>100,<br>function(){$("#row16").animate({ "opacity": "0" },<br>100,<br>function(){$("#row15").animate({ "opacity": "0" },<br>100,<br>function(){$("#row14").animate({ "opacity": "0" },<br>100,<br>function(){$("#row13").animate({ "opacity": "0" },<br>100,<br>function(){$("#row12").animate({ "opacity": "0" },<br>100,<br>function(){$("#row11").animate({ "opacity": "0" },<br>100,<br>function(){$("#row10").animate({ "opacity": "0" },<br>100,<br>function(){$("#row9").animate({ "opacity": "0" },<br>100,<br>function(){$("#row8").animate({ "opacity": "0" },<br>100,<br>function(){$("#row7").animate({ "opacity": "0" },<br>100,<br>function(){$("#row6").animate({ "opacity": "0" },<br>100,<br>function(){$("#row5").animate({ "opacity": "0" },<br>100,<br>function(){$("#row4").animate({ "opacity": "0" },<br>100,<br>function(){$("#row3").animate({ "opacity": "0" },<br>100,<br>function(){$("#row2").animate({ "opacity": "0" },<br>100,<br>function(){$("#row1").animate({ "opacity": "0" },<br>100)})})})})})})})})})})})})})})})})})})})
You can see the full source<br>here and the final product<br>here.
(I even went through the trouble of indenting each callback properly, a<br>nontrivial feat in Windows Notepad.)
Note that the Javascript ends with a flourish:<br>)})})})})})})})})})})})})})})})})})})}). At the time I was just glad that my<br>triangles were disappearing and reappearing as intended. The code itself was<br>like a magnificient ASCII waterfall or those Incan irrigation systems I often<br>saw in AP Spanish. It worked, and nothing I read on Google told me that things<br>were actually terribly wrong and that any programmer who read my code would<br>never let me nor my progeny near the web again.
By the first time a real software engineer took a look at my triangles code, I<br>had already read enough of SICP to realize that my code was something ghastly<br>and terrible. "But any beginner would make the same mistake, right?" I probed,<br>embarrassed.
"No, no programmer would do something like this." He was not sarcastic. I wanted to<br>switch back into Molecular and Cellular Biology right then. But then he added,<br>"No...