First, I've looked at related SO questions, and didn't find much in the way of a suitable answer, so here goes:
I've been working on an HTML/Javascript page that acts as a UI to a back-end server. I made some pretty good strides in completing it, all while using synchronous calls in AJAX (aka var xmlhttp = new XMLHttpRequest(); xmlhttp.open(type, action, false);
), but have now come to find out that Mozilla apparently doesn't like synchronous requests, and has therefore deprecated some much-needed functionality from them.
To quote https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest:
Note: Starting with Gecko 11.0 (Firefox 11.0 / Thunderbird 11.0 / SeaMonkey 2.8), as well as WebKit build 528, these browsers no longer let you use the responseType attribute when performing synchronous requests. Attempting to do so throws an NS_ERROR_DOM_INVALID_ACCESS_ERR exception. This change has been proposed to the W3C for standardization.
So that's great. I'm about to need to change the response type conditionally, but it won't work. It is now my intention to wrap an AJAX asynchronous request in something that will simulate synchronicity.
The following is a generic "make web request" function that my code uses, that I've started adapting to work for my purposes. Unfortunately, it isn't working quite like I'd hoped.
var webResponse = null;
function webCall(action, type, xmlBodyString) {
console.log("In webCall with " + type + ": " + action);
webResponse = null;
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState == 4)
{
if (xmlhttp.status == 200) {
webResponse = xmlhttp.responseXML;
} else {
var statusTxt = xmlhttp.statusText;
if (statusTxt == null || statusTxt.length == 0) {
statusTxt = "An Unknown Error Occurred";
}
throw "ERROR " + xmlhttp.status + ":" + statusTxt;
}
}
}
xmlhttp.open(type, action, true);
if (xmlBodyString == null) {
xmlhttp.send();
} else {
xmlhttp.setRequestHeader("Content-Type", "text/xml");
xmlhttp.send(xmlBodyString);
}
for (var i = 0; i < 20; i++) {
if (webResponse != null) {
break;
}
window.setTimeout(nop, 250);
}
if (webResponse == null) {
throw "Waited 5 seconds for a response, and didn't get one.";
}
console.log("Responding with " + webResponse);
return webResponse;
}
function nop() {
}
So, I thought this was pretty straight-forward. Create a global variable (in retrospect, it probably doesn't even have to be global, but for now, w/e), set up the onreadystatechange to assign a value to it once it's ready, make my asynchronous request, wait a maximum of 5 seconds for the global variable to be not null, and then either return it, or throw an error.
The problem is that my code here doesn't actually wait 5 seconds. Instead, it immediately exits, claiming it waited 5 seconds before doing so.
I made a fiddle, for what it's worth. It doesn't work in there either. http://jsfiddle.net/Z29M5/
Any assistance is greatly appreciated.