DAVE'S LIFE ON HOLD

Beautiful Code and Idiosyncratic Programming

Recently I showed a friend some code that looked like this:

catch(e) " href="http://2.bp.blogspot.com/_XCDTVvEbBMU/TUy2UfN28zI/AAAAAAAAAFs/ufgiV49Jh-4/s1600/Screen%2Bshot%2B2011-02-04%2Bat%2B9.29.43%2BPM.png">

When executed it does:

catch(e) " href="http://1.bp.blogspot.com/_XCDTVvEbBMU/TUy2h7UX65I/AAAAAAAAAF0/WXm6uNuFDJk/s1600/Screen%2Bshot%2B2011-02-04%2Bat%2B9.29.51%2BPM.png">

And then:

catch(e) " href="http://3.bp.blogspot.com/_XCDTVvEbBMU/TUy2qLeYptI/AAAAAAAAAF8/aRv2VdLRm2M/s1600/Screen%2Bshot%2B2011-02-04%2Bat%2B9.29.57%2BPM.png">

This example displays how a String that looks like a URL can work like a URL. It also shows how we can asynchronously define a callback for an asynchronous fetch. It also demonstrates how we can chain callbacks to define a progression of states. It all starts with a very simple bit of code:


String.prototype.get = function(cb,data)  return this.request(


Which invokes a slightly more complex bit of code, that does a XHR fetch


String.prototype.request = function(method,data) <br />        var _request = XMLHttpRequest ? new XMLHttpRequest(): _doc.createRequest();<br />        var cb = function () {<br />                if (this.readyState != 4) return;<br />                if (this.status == 404) cb.process(null);<br />                if (this.status == 200) cb.process(this.responseText);<br />        ;
_request.onreadystatechange = cb;
_request.open(method,this,true);
_request.setRequestHeader('Content-Type','text/plain');
_request.send(data ? data : '');
return cb;
}


The key bit here is that the closure invokes cb.process() and returns the callback as the final operation. The way that the process method works:


Function.prototype.process = function() this.Pending.apply(this.Pending,arguments);
" alt="
if (typeof(this.Pending) == "function")
this.Pending.apply(this.Pending,arguments);
" />


Which simply calls the "Pending" property of the callback function, which holds the chain of callbacks. We set this property in the original bit using the then() function:


Function.prototype.then = function(f)  <br />        var me = this;<br />        this.Pending = function() { <br />                var results = f.apply(f, arguments); <br />                if (!results) results = [];<br />                f.process(results);<br />
return f;
}


where in we wrap the callback we're passed in another function which knows how to apply it to whatever arguments we pass to it via process(). For the chain, we pass the results of each function as the arguments to the next, allowing us to perform a sequence of transformations and share state.

This technique also works beautifully for adding timer callbacks for generating asynchronous processing using the setTimeout interface. In this way we can declare behavior in a straight forward manner.