Submitted on Monday, 7/13/2009, at 11:33 PM

AJAX (Asynchronous JavaScript and XML) is a technique that lets web pages update themselves with remote data without reloading the entire page, greatly increasing their interactivity. It uses JavaScript to change the content of the page, and the non-standard function XMLHttpRequest() to talk to remote web servers to obtain or provide new data. All of this occurs in the background, allowing the user to interact with other elements on the page at the same time.

AJAX is described in many places on the web and in technical books, but from what I've seen the usual examples are not truly asynchronous, as rapid multiple requests by the user can collide with each other. The following is typical code:

var request;

function action() { request = new XMLHttpRequest(); // Browser variation and error catching code should be here, too'GET', 'action.php'); // Open a connection to this URL, in this case a local page
request.onreadystatechange = handle_action; // Function to process the request results on completion
request.send(null); // Send the request, which proceeds in the background
   return 0; // Returns control of the browser to the user

The basic problem is in the request variable, which is set up as a global so that the function handle_action can reference the returned data it contains. This means that a second request of the same type can possibly overwrite the previous request before it has completed its assigned task! And it's not truly asynchronous if it doesn't control its own state.

The following variation fixes the issue:

function action()
    var request;
    request = new XMLHttpRequest();'GET', 'action.php');
request.onreadystatechange = function () { return handle_action(request); };
  return 0;

By making request a local variable and providing it as a parameter to the request handler, each request has independent status. The request handler is implemented as an anonymous function and a closure, which preserves a reference to the local variable even after the parent function exits.