<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>getiblog &#187; chaining</title>
	<atom:link href="http://blog.getify.com/tag/chaining/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.getify.com</link>
	<description>javascript, performance, and ui musings</description>
	<lastBuildDate>Thu, 15 Dec 2011 17:37:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Simulated Chaining in JavaScript</title>
		<link>http://blog.getify.com/simulated-chaining-in-javascript/</link>
		<comments>http://blog.getify.com/simulated-chaining-in-javascript/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 16:18:04 +0000</pubDate>
		<dc:creator>getify</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[chaining]]></category>
		<category><![CDATA[functions]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[labjs]]></category>

		<guid isPermaLink="false">http://blog.getify.com/?p=213</guid>
		<description><![CDATA[What I have to talk about here is not going to be earth shattering, but it is a technique that has proved useful in a few different sites and scenarios for me. In fact, I regularly get questions regarding advanced use cases for LABjs (a parallel JavaScript loader), and invariably it comes back to something [...]]]></description>
			<content:encoded><![CDATA[<p>What I have to talk about here is not going to be earth shattering, but it is a technique that has proved useful in a few different sites and scenarios for me. In fact, I regularly get questions regarding advanced use cases for <a href="http://labjs.com">LABjs</a> (a parallel JavaScript loader), and invariably it comes back to something along these lines.</p>
<p>If you already understand object/function call chaining, just <a href="#goodstuff">skip down to the good stuff</a>.</p>
<h2>The chains that bind you</h2>
<p>Just so we&#8217;re all on the same page, &#8220;chaining&#8221; is this wonderful functional property of languages like JavaScript (which treat a function as a first-class citizen). It essentially amounts to making a function call, and the return value from the function is itself either another callable function, or more often, an object that has functions which are directly callable.</p>
<p><a href="http://jquery.com">jQuery</a> is probably the most prevalent use of this concept. Some example jQuery code:</p>
<pre class="code">
$("p.neat").<strong>addClass</strong>("ohmy").<strong>show</strong>("slow");
</pre>
<p>In this snippet, <code>$(...)</code> is actually a function call, just like <code>foo(...)</code> or <code>doSomethingReallyEvilButDontTellAnyone(...)</code> (just kidding; only Google would name a function something crazy like that).</p>
<p>The return value from the <code>$(...)</code> call is an object, that has a bunch of properties on it, many of whom are functions. Consider that conceptually an object is returned like this (not actual code):</p>
<pre class="code">
function $(...) {
   // do something cool
   return {
      addClass:function(...){...},
      show:function(...){...},
      ...
   };
}
</pre>
<p>So, what happens is that when that object is returned from the function, JavaScript will allow you to immediately <em>de-reference</em> the return value (the object), and using &#8220;.&#8221; (dot notation), access its properties. So <code>$(...).<strong>addClass(...)</strong></code> makes the first chained call (&#8220;addClass&#8221;) off the return value from <code>$(...)</code>. Then, <code>addClass(...)</code> also returns the same (same kind, not identical) object, and so this second return value can identically be de-referenced and a chained function be called. I like to refer to each chained function call as a &#8220;chain link&#8221;.</p>
<p>This chaining can theoretically go on forever (although for code readability it can be argued that 3 or 4 chain links is probably the most you want to practically do in production code, exceptions aside).</p>
<h2>Why chains?</h2>
<p>Probably the single biggest argument for developing code API&#8217;s that are of this chaining style is to pass context along from one function call to another in an automatic and graceful feeling way. For instance, in jQuery&#8217;s case, the reason for chaining is that internally, there&#8217;s a collection (a fancy array) of objects, and as each chained function is called, internally it loops over the collection of objects and performs tasks (such as expanding/contracting the collection, modifying objects in the collection, etc).</p>
<p>jQuery could work functionally this way and achieve the same effect:</p>
<pre class="code">
var collection = $("p.neat");
$.addClass(collection,"ohmy");
$.show(collection,"slow");
</pre>
<p>See how we had to pass in the &#8220;collection&#8221; object/array for every function call? It works, but that code is arguably a little less graceful. And certainly it&#8217;s a little more repetitive.</p>
<p>So, chaining was a way to accomplish the same task (context passing across function calls) but in a prettier, more graceful fashion. Generally, the idea of adjusting the way a set of code works to make it more expressive or pleasant is called adding &#8220;syntactic sugar&#8221;.</p>
<p>To be fair, syntactic sugar is not the only reason why chaining in functional languages is useful. In fact, with LABjs, which also has a similar type of chaining API (although internally operates quite differently from jQuery), the reasons were only partially &#8220;sugar&#8221;; chaining in LABjs&#8217; case actually provides an effective solution to guard against certain types of race conditions. </p>
<p>Because of how JavaScript (single-threaded) works, a chain of function calls is more or less guaranteed to complete fully before any other code comes in and interrupts to execute. This is also <em>probably</em> true of a series of distinct function calls in a single code block, but even more definitely so for a chain of function calls or (as we&#8217;ll see in a moment), a loop of function calls.</p>
<h2>So why not a chain?</h2>
<p>Since chains are powerful and also tend to lead to more expressive code (unless abused) and also generally <em>less code</em>, you may wonder, why wouldn&#8217;t we always use chains for everything?</p>
<p>The obvious: some function calls are, by their nature, independent and thus do not need to (or should not!) share a context. Also, under certain circumstances, chaining can be less efficient internally, depending on how the context is stored/shared/used.</p>
<p>Let&#8217;s face it: if you really want to write your entire &#8220;program&#8221; on one line with a bunch of obscure/abusive syntactical tricks, just go write some Perl. I kid, I kid.</p>
<p>But beyond those things, one fundamental fact of chaining is that it&#8217;s not &#8220;dynamic&#8221;. Basically, what I mean by this is that you pretty much hard-code at the time of code writing (aka, &#8220;build time&#8221;) how a chain is constructed. You can&#8217;t decide at run time based on environmental conditions that some parts of the chain are conditionally not executed (like by wrapping them in an if-statement, etc). </p>
<p>The ability to do that kind of run-time logic is restricted syntactically to individual statements/function calls, so a chain will be considered an atomic single indivisible unit for those purposes. You could conditionally decide whether to run one of several different chains depending on conditions, but each chain to be chosen would be pre-defined and for the most part immutable.</p>
<p>So, the truth is, chaining provides a syntactically prettier (more expressive) code approach, but it limits us a little bit in terms of coding flexibility.</p>
<h2>I need more concrete</h2>
<p>To illustrate, let&#8217;s revisit jQuery&#8217;s example code from above. Let&#8217;s say instead that what you really want to do is only run the <code>addClass(...)</code> call if some condition is true (like for instance, the user has a valid login session, or whatever). So, you want to basically do conceptually something like this:</p>
<pre class="code">
$("p.neat")
<strong>if (userLoggedIn()) {</strong>  .addClass("ohmy")  <strong>}</strong>  // invalid syntax; will not work!
.show("slow");
</pre>
<p>As I mentioned, you could just have two different chains, one with <code>addClass(...)</code> in the chain, one without it, and choose which chain to execute with your if-statement. This leads to more and repetitive code; a bad thing. DRY (don&#8217;t repeat yourself).</p>
<p>And to be honest, you could also model this in a pure jQuery way (only in the chain using various filters), a variety of different ways. For instance, something like this (while ugly) might work:</p>
<pre class="code">
$("p.neat")
.filter(function(){
   return isLoggedIn();
})
.addClass("ohmy")
.end() // ends the most recent filtering operation
.show("slow");
</pre>
<p>What I did here was use <code>filter(...)</code> to basically conditionally empty out the internal collection if not logged in (by returning false for all iterations), meaning the <code>addClass(...)</code> call is essentially ignored, and then revert back to my original collection with a <code>.end()</code> call before lastly calling <code>.show(...)</code>.</p>
<p>Let me be clear: while you <em>can</em> do it this way, this is by far not the most efficient or code-friendly way to do so. This would be an example of an anti-pattern, where you are abusing jQuery&#8217;s syntax to solve a problem in a way that it should not be solved. It goes contrary to the spirit of jQuery (&#8220;write less, do more&#8221;).</p>
<h2>Other examples?</h2>
<p>Conditional inclusion of &#8220;chain links&#8221; is only one scenario where traditional chaining is kind of limiting. What if you want to be able to piece together different parts of a chain from various different snippets of code across mutliple functions? This may sound strange, but with complex Web 2.0 web applications, this kind of thing is not uncommon. And it flys in the face of the simple syntactic sugar that chaining is supposed to give us.</p>
<p>Nor are these problems limited to jQuery. With LABjs for instance, a chain might look like this:</p>
<pre class="code">
$LAB
.script("framework.js")
.script("loggedin.js")
.wait(function(){
  // do something
});
</pre>
<p>Notice there I may want to <em>only</em> load &#8220;loggedin.js&#8221; if the user is, in fact, logged in. Same syntactic problem as above. But LABjs has no conditional &#8220;filters&#8221; that can modify the chain&#8217;s context, so we have less options (which in this case is a good thing!)</p>
<p>Or, what if I have a CMS system (like WordPress for instance) that, across various functions, files, templates, etc, needs to load up a variety of different files, all based on various different environmental conditions and which templates are active, etc. Could I do individual $LAB chain calls in each location? Yes. But then I lose the ability to sequence the loads (ensure execution order). Also, it&#8217;s less memory efficient to do 8 different chains with 1 script in each, as opposed to one chain with 8 scripts in it.</p>
<p>Or, what if I want to use LABjs in a larger solution for <a href="http://happyworm.com/blog/2010/01/28/a-simple-and-robust-cdn-failover-for-jquery-14-in-one-line/">creating robust fallback for resource loading from CDN locations</a>? I need to conditionally decide during loading/run-time if I need to add more scripts to the &#8220;queue&#8221; because one load failed. Not possible with traditional chaining.<br />
<a name="goodstuff"></a></p>
<h2>Unravel the ball of yarn</h2>
<p>All this leads up to say that chaining is great and expressive and powerful, but it&#8217;s not complete for all our needs. So, we need to get a little more creative in those cases. And this technique is what I&#8217;m going to call &#8220;Simulated Chaining&#8221;.</p>
<p>Recall that at the top of this post, we talked about how chaining works because the <em><strong>return value</strong></em> from a function is either a function itself (and thus can be called directly), or it can be an object that can be de-refenenced and has properties which are functions to be executed.</p>
<p>So, our solution lies in that sentence (emphasis added). The <em><strong>return value</strong></em> from a function can either be used immediately, or it can be stored and used later. This isn&#8217;t anything new; if you&#8217;ve ever called any function in any language, you know it can return a value that you can store in a variable. What might have escaped you until now is that this return value that you store can be a contextually sensitive object that would otherwise have been used immediately in a chaining situation. And the cool part is it can be used later (like the next loop iteration) to pick up where the chain left off.</p>
<p>So, instead of pre-defining a chain in our code/build-time, we can instead programatically (at run-time) build up a &#8220;list&#8221; (an array/queue for instance) of functions to be called, and then &#8220;simulate&#8221; a chain by looping through the list, calling each function, and storing the return value for use in the next iteration.</p>
<p>For instance, the LABjs script code above can be done like this instead:</p>
<pre class="code">
var queue = []; // empty array for now
...
queue[queue.length] = "framework.js";
...
if (isLoggedIn()) { queue[queue.length] = "loggedin.js";
...
var $L = $LAB;
for (var i=0, len=queue.length; i&lt;len; i++) {
   $L = $L.script(queue[i]);
}
$L.wait(function(){
   // do something
});
</pre>
<p>I <em>simulated</em> a chain of function calls with an iterative for-loop. (NOTE: this is conceptually very similar to how you might take what would otherwise be a recursive set of function calls and turn it into a non-recrusive, iterative loop instead, like for performance reasons). The key is: store the return value from a function call, and then use that stored value as the object that makes the next call. Plain and simple. And now more powerful as you can build up your chains at run-time in as complex a way as is necessary.</p>
<p>Theoretically, a very similar approach could be taken for the jQuery examples above. However, I&#8217;ll leave that as an exercise for the reader.</p>
<p>Let&#8217;s look at one last slightly more advanced example of how to use simulated chaining with LABjs (which is nearly identical to how I do it on several of my sites):</p>
<pre class="code">
var queue = [];
...
if (conditionOne()) {
   queue.push("framework.js",false); // false will create an empty .wait()
}
...
if (conditionTwo()) {
   queue.push("plugin1.js","plugin2.js",function(){
      // initialize plugins
   });
}
...
queue.push("mypage.js");
...
var $L = $LAB;
for (var i=0, len=queue.length; i&lt;len; i++) {
   if (typeof queue[i] === "function") $L = $L.wait(queue[i]);
   else if (queue[i] === false) $L = $L.wait();
   else $L = $L.script(queue[i]);
}
</pre>
<p>I specify a queue array that can have one of three types of entries: a [string] is interpreted as a script to load, a [false] is interpreted as an empty .wait() call, and a [function] is passed to a .wait(&#8230;) call. I can use any manner of complex logic to build up the queue, and then in one for-loop at the bottom of the page, simulate the chain by looping over the queue.</p>
<p>Hopefully this helps clear up some of the mysticism that is chaining and give you some other ways to approach the challenging use cases you may face in your code. Go forth and chain (or loop)!</p>
<div><a class="addthis_button" href="//addthis.com/bookmark.php?v=250" addthis:url='http://blog.getify.com/simulated-chaining-in-javascript/' addthis:title='Simulated Chaining in JavaScript '><img src="//cache.addthis.com/cachefly/static/btn/v2/lg-share-en.gif" width="125" height="16" alt="Bookmark and Share" style="border:0"/></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.getify.com/simulated-chaining-in-javascript/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Content Delivery Network via getiblog.2static.it

Served from: blog.getify.com @ 2012-05-18 09:25:05 -->
