Multiple requests through xmlhttprequest object

I’ve been working on a calendar page that builds the entire calendar through Javascript and retrieves the entries from a server by using a xmlhttprequest-object. I have been able to create this without too many problems. However, now I have to retrieve entries from multiple different sources, but I can’t get it to work. I think it has something to do with the fact that the entries are parsed in the readystatechange event. My guess is that the parser is still working on the first results, when the next results come in and overwrite the previous data.

I’m guessing some thought has already gone into this and someone knows how to overcome this problem. To give a simplified example of my problem:


xmlhttp = createXMLHTTP(); // creates a XmlHttpRequest object, browser dependant
urlList = new Array("url1", "url2");
for (var x = 0; x < urlList.length; x++) {
  xmlhttp.open("GET", url[x], false);
  xmlhttp.onreadystatechange = handleStateChange; // function that processes the resulting XML data
  xmlhttp.send(null);
}

In this example, the data from url1 will never be shown.

I encountered the same problem. I used a queue to solve the problem:


//this allows detection of XMLHttpRequest without crashing IE
try { new XMLHttpRequest() } catch(e) { XMLHttpRequest = null }

var xmlHttpReqQueue = new Array()
function requestXML(url) {
	var xmlHttpReq
	if (XMLHttpRequest) {	//Mozilla
		xmlHttpReq = new XMLHttpRequest()
		xmlHttpReq.onload = function () {
			xmlHttpReqQueue.shift()
			//send the next request if queue isn't empty
			if (xmlHttpReqQueue.length > 0)
				xmlHttpReqQueue[0].send(null)
			doStuff()
		}
	} else if (window.ActiveXObject) {	//IE
		xmlHttpReq = new ActiveXObject('Msxml2.XMLHTTP')
		xmlHttpReq.onreadystatechange = function () {
			if (xmlHttpReq.readyState != 4)
				return
			xmlHttpReqQueue.shift()
			//send the next request if queue isn't empty
			if (xmlHttpReqQueue.length > 0)
				xmlHttpReqQueue[0].send(null)
			doStuff()
		}
	}
	xmlHttpReq.open('GET', url, true)
	xmlHttpReqQueue.push(xmlHttpReq)
	//if queue was previously empty, there is no request being sent
	//so send this request immediately
	if (xmlHttpReqQueue.length == 1) {
		xmlHttpReq.send(null)
	}
}

Scavanged from my own code, so this exact code isn’t tested.

You need “onreadystatechange” only if you’re doing async request. Since your requests are synchronous, you can parse results immediately after “send” line in your code:


for (var x = 0; x < urlList.length; x++) {
  xmlhttp.open("GET", url[x], false);
  xmlhttp.send(null);
  do_something_with(xmlhttp.responseXML)
}