Introducing the deferred jQuery chain

After long time working with jQuery in different projects we found that there was one thing we always (re)invented again – convenient methods for timing. Of course, using window.setTimeout() and window.setInterval() is not a big deal. But it becomes one if you leave the easy examples and implement really sophisticated use cases. So at the end we decided to write this plugin you are studying right now – jquery-timing.

With this plugin we use a new technique that we call the Timed Invocation Chain (or in short: tic).

Our chaining concept is much more than just another try to implement John Resig's idea of ultra-chaining. First we started with similar aims. But we didn't stop there, we went further and created an API as neat as it can be.

Sit back, relax, and enjoy your code getting shorter and cleaner.

jQuery and its invocation chains

The timed invocation chain technique provides an easy way to postpone method execution when written in a jQuery style – a long method call concatenation, always using the return value of the previous function call as context to work on with the next function. jQuery highly bases on exactly that method concatenation schema:

$('.some').show().css({..}).click(function(){..}).find(..)
  .hover(..).keypress(..)​​.first(..).css(..).each(..) // etc

And that's the point!
Using a method on jQuery selection objects almost always returns the same or another jQuery object to work with. So it is an invocation chain where all objects in between again are jQuery selection objects.

Creating a Lazy Proxy

If you know that any object result within a long invocation chain is of the same type (or for other programming languages the same class or interface), then you also know that they share a common set of methods that can be invoked. In our case we just have to look at the very first object, $('some'), and list all the methods that can be invoked on that object. We then can forecast that each and every invocation step in the long invocation chain will allow us to call exactly these methods.

All we have to do on the first call to one of our timing methods is to internally create a smart placeholder object being aware of all the methods that could be called (this is the lazy proxy or predictive proxy pattern). When the methods are actually called in the invocation chain, meaning when the JavaScript engine does execute the code, then the lazy proxy collects all invocations in a call stack. It stores the function names and the arguments given to each call.

A fluent interface as meta language

The outcome of the lazy proxy is a call stack that allows us to iterate all the method invocations in any possible manner. With this call stack in our hands we can do a lot of cool things. For example we can create a fluent interface even for asynchronous situations. This will make your source code neat and clean – exactly that's the aim of this project.

The lazy proxy pattern allows to build a timed invocation chain wherever we have such a strong chaining concept like in jQuery. Applying that new technique to jQuery produces a new kind of jQuery object – the Deferred jQuery Chain.

jquery-timing as reference implementation

Our concept of the predicting proxy and the timed invocation chain technique have been developed in summer 2012. To prove their functionality we implemented them as plugin for jQuery to cover as much asynchronous and repetitive situations as possible. Thus you can speak of jquery-timing plugin being the reference implementation for this new fluent interface.

Instant invocation and Recursion-freeness

Two of the amazing capabilities of jquery-timing are: loops and instant invocation. Both are described in detail on the following pages.
For now we want to explain why we decided for a recursion-free design when applying the timed invocation chain to jQuery:

Imagine you want to add very many table rows automatically so you can fill them with dynamic content.
E.g. a 30 x 200 sized table in a single jQuery line:

$('table').repeat().append('<tr>').until(200).children().repeat().append('<td>').until(30);

If we had implemented our instant repeat-loops the simple way with just recursive method calls, then we could cause a stack overflow here. Because hundreds of nested method calls would all have to stay on the method stack of your client's JavaScript interpreter.
That's why the heart of the deferred jQuery chain – the internal function timedInvocationChain() – consists of a single while-loop that omits recursive calls. For you, the developer this means to have no sorrows about the size of instant invocation loops.


introduction to deferred jQuery chaindelays in the invocation chain