Polling AJAX Using When.js with jQuery AJAX Promises

Abstract: Using when.jspoll command together with jQuery’s Ajax methods yalst operator clients written in Javascript can define their data update loop with a minimal amount of code.

Contents

  1. The Problem
  2. The Principle Of Promises
  3. When.js’ Poll Method
  4. The Monitor Code
  5. References

The Problem

When implementing a web page like the yalst operator console which monitors frequently changing data the most reliable and most compatible method is still rapidly polling of Ajax requests. A number of websocket implementations use Ajax polling as a fallback in case the web socket connection can not be established[1].
Both the issuing of Ajax requests and periodically executing a worker function are common tasks when building web applications and are abstracted in many library implementations.

The Principle Of Promises

A Promise-based interface provides a nice way to decouple the asynchronous internals of the network operation from the application program flow.

A general description is that a promise encapsulates the final result of an asynchronous operation. A promise may be in one of the three states, "pending", "resolved", and "rejected". The promise itself accepts callbacks via its then method.[2]

Which means that instead of specifying callback functions in the call of an asynchronous operation that operation simply returns a promise (so to speak a “promise” of its eventual result).

This diagram depicts the basic features:
Time sequence of asynchronous I/O using a promise object to wrap the results.

Time sequence of asynchronous I/O using a promise object to wrap the results. The gray box groups an alternative line of execution. [3].

The advantage is that it is easy to compose new promises from existing ones. Examples are

  • The combined promise all which resolves not until all given promises resolve (e.g. loading a bunch of images before displaying the slide show).
  • The competitive promise any which evaluates to the return value of the promise whichever one completes first (e.g. timing out an operation by combining it with a timeout promise)
  • The propagation/forwarding of promises by returning a new promise from a then callback. E.g. when polling Ajax in case the reason for an Ajax failure was a timeout condition the onRejected() handler could resolve a newly created promise with a default value an return that promise. Thus the poll control loop is not interrupted.

Another advantage is that sequential chains of asynchronous logic actually appear sequential with promises rather than with the unwieldy nesting patterns of callback functions [5].

The Libraries

Usually the first candidate for a library implementation is always the well-established jQuery library. Fortunately it’s Ajax objects already implement a promise interface, well done! However to repeatedly poll a worker promise neither jQuery nor underscore i.e.Low-Dash provide suitable methods.

Browsing for other promise libraries the simple API of When.js [4] stands out. It’s features include

    • important combinators like map, all, any, pipeline, sequence, parallel,…
    • convenient utility promises like timeout, delay and poll
    • coexisting with jQuery promises and
    • transforming other callback-based APIs into promise-based APIs, e.g. when loading an image:

When.js’ Poll Method

The When.js poll method will

“execute a worker task repeatedly at the specified interval ΔT, until the shouldFinish condition function returns true. The resultPromise will be resolved with the most recent value returned from worker. If worker fails (throws an exception or returns a rejected promise) before shouldFinish condition returns true, the resultPromise will be rejected.” [4]

which is an excellent choice for wrapping the jQuery Ajax worker function for our purpose.

However since there are two different promises involved now the program flow can get confusing. In order to clarify their dependence the next digram depicts all possible outcomes of this combination. Due to this article’s format the time axis is rotated pointing from top to bottom.
Using when.js poll method with a worker function returning a jQuery promise

Using when.js poll method with a worker function returning a jQuery promise. The gray boxes group alternative lines of execution. Please feel free to verify his behaviour in this JsFiddle.

The Monitor Code

As “promised” here is the final code which defines the monitoring loop in the yalst operator console.

References

[1] see the section “Pushing and Polling” at http://blog.fogcreek.com/the-trello-tech-stack/
[3] idea for the diagram shamelessly taken from NetTuts+
[5] David Herman: “Effective Javascript” , 2012 by Addison-Wesley, http://effectivejs.com