Making Multiple Simultaneous Requests with AJAX in JavaScript

This article looks at how we can iterate through a set of different items on a page using JavaScript, and get further information on each in the background via AJAX. Once the AJAX calls get the extra information, we can update the items on the page. What is different about the approach shown here to others you may be accustomed to is that multiple AJAX requests are made simultaneously, allowing us to retrieve information for an indeterminate number of page items at once, allowing us to keep multiple content zones independently updated.
compton, 4 March 08
Updated 26 January 11
AJAX is great for creating pages which show data that is dynamically kept up-to-date in real-time, such as a page showing live market prices for stocks and shares, or a page on a betting site showing live odds for upcoming sporting events. Without AJAX, pages like this would need to be coded to automatically refresh after a set interval; a somewhat messy experience for the end-user.

Often, as in the two examples above, you can update all the data items together using a single AJAX call. You would set a JavaScript function to run at the predetermined interval, its job being to retrieve the latest prices with a single call, and parse the data to update each data cell on the page. Most often, an XMLHttpRequest object is created as a global JavaScript variable. It will be reused for each background content-fetch required. Use of a global variable simplifies some aspects of the coding, but it does mean that you can only make one AJAX request at a time.

Sometimes though, the data for each item can't all be obtained at the same time. In this particular case, I needed a page to show the status of multiple servers via the internet. I didn't want each update to have to wait for the slowest responding server, and nor did I want each request to have to queue while earlier ones completed. To complicate things, the number of servers shown on the page was variable.

My solution took the form of a JavaScript array, which would hold multiple XMLHttpRequest objects. Each one can independently and simultaneously make requests, and update the page data in the background. It is declared with global scope:
ajaxArray = new Array();
The page with this code shows a table with a different server in each <td> cell. The JavaScript's objective is to display live information about each server. For simplicity's sake, the code here deals with a single item of data for each server - a status of AVAILABLE, UNAVAILABLE, or TIMEOUT.

Inside each table cell is a <span> element with an id of check_[server address], and the <span> itself contains the name of the server as text. This means we can iterate through all the <span>s, set off an AJAX request for each, and then update each <span>'s contents as our AJAX calls complete.

As a small optimisation, we can give the table an id attribute of line_table, so we only need iterate through spans within that table:
function checkServers() { var spans = document.getElementById('line_table').getElementsByTagName('span'); for (var thisSpan = 0; thisSpan &lt; spans.length; thisSpan++) { if (spans[thisSpan].id.substr(0, 6) == 'check_') { statusCheck(spans[thisSpan].id.substr(6)); } } }
Using document.getElementById('line_table').getElementsByTagName() is a minor optimisation and document.getElementsByTagName() would work just as well but not quite as efficiently, especially if you have a lot of <span> elements elsewhere on the page. In either case, the getElementsByTagName() function returns an array of 'live' nodes of the requested type, which we can then iterate through with a for loop as shown. Breaking up each <span>'s ID into its two parts is easy enough using substr(), and we then pass the server address to the checker function (statusCheck()).

It's the statusCheck() function which initiates the AJAX calls to actually check the availability of a server. As mentioned, the global array variable called ajaxArray will hold our XMLHttpRequest objects. The first thing the statusCheck() function needs to do then is find an empty slot in this array. This is pretty easy:
function statusCheck(serverAddress) { var index = 0; // Find an empty slot in the AJAX array while (ajaxArray[index] &amp;&amp; index &lt; &lt;?= MAX_SIMULTANEOUS_AJAX_REQUESTS; ?&gt;) index++;
Note the PHP constant MAX_SIMULTANEOUS_AJAX_REQUESTS, which lets me determine the maximum number of AJAX objects to have going at any one time in my PHP code.
1 2 3