today | current | recent | random ... categories | search ... who ... syndication

Thursday, November 18 2004

XMLHttpRequest API madness

Part of the Daily Hustle involves setting aside a couple hours, each day, to learn something new. I have always been curious to play with the JavaScript XMLHttpRequest functions so, as an exercise, I implemented the del.icio.us social bookmarking and languid language identifier APIs in JavaScript.

 

Both libraries are synchronous : they will block the browser from performing other actions during the time in which they are talking to the remote server. This means that they may not always be the right choice for your application.

Typically, applications built using data retrieved from a remote location are designed to allow the browser to keep processing user events : scrolling down the page, opening a new window, etc. The request is initiated with a pointer to a function, a callback in the nomenclature, which is processed when the chatter between the client and server is complete. Both the chatter and the callback are exceuted, and given prioroty, as part of the normal queue of browser events.

Since most tools that use XMLHttpRequest do so in order to update some aspect of the current page, this is a perfectly good way to approach the problem. On the other hand, it's not so great when you're trying to do something like this :

var delicious = new Delicious(...);
var posts     = delicious.posts();
    

In an asynchronous world, the return value of posts is set before the method has gotten around to processing the actual request to the remote server :

function posts () {
    var amiasynchronousoraminot = (true|false);

    var uri = "http://example.com/posts/get";
    var ua  = this._xmlhttprequest();

    ua.open("GET",uri,amiasynchronousoraminot);
    ua.send(null);

    var res = ua.responseXML;
    return this._processreponse(res);
}    
    

If the amiasynchronousoraminot variable is true, then as soon as the send method is invoked, the program immediately moves on to the next processing instruction : res = ua.responseXML. Assuming, for the sake of argument, that this didn't already raise a JavaScript error, res would still be empty since it is defined before responseXML even has a value. And so on, until the JavaScript interpreter assigns the same null value to posts. Which is not what we had in mind.

This is not an impossible problem. You could set up a series of callbacks to process and watch for specific events and trigger the next in a long series of actions. Not impossible but it's a lot of code and one of the benefits of using an API is that you can just say : var posts = delicious.posts(). The trade-off, in this instance, is that in order to do so the code that talks across the network needs to block. Buyer beware.

Finally, it goes without saying that you should use this code, specifically the delicious library, with some care and courtesy. For example, if you operate a high-traffic website and decide to include a dynamic list of your delicious bookmarks you are likely to run a foul of the service's creator in short order.

 

refers to

meta

Me : XPointerHttpRequest.js 1.0

 

From the docs : XPointerHttpRequest is a JavaScript library to request (remote) XML fragments using XPointer and the HTTP 1.1 Range and Accept headers, as described in the paper : A Semantic Web Resource Protocol: XPointer and HTTP.

Unlike the delicious and languid JavaScript libraries, this one lets you define a callback if you want to use it asynchronously.

Aside from using it in the browser there is something about the idea of using this in an SVG application that excites me. No idea why, yet...

 

refers to

meta

 
 
Wednesday, November 17 2004 ←  → Sunday, November 21 2004