As

J

JT

Asynchronous JavaScript

I am building a Web App which relies heavily on asynchronous
javascript (XMLHttpRequest).

It works a beautifully in IE7 and FF 2+ , but in IE6 (6.0.2900.2180
((sp2)) even though the asynchronous flag is set to true the call is
synchronous and doesn’t fork!! This problem is sporadic, only
happening on some peoples PCs some of the time and not others (with
the same full version as seen in Help->About). My code to test and
demonstrate this is as follows:.

The variables onExitRoot and callerHasLeft are used to test if the
Http Request was processed asynchronously..

Any ideas why this doesn’t work on some versions of IE6…

try
{
var onExitRoot = false;
var callerHasLeft = false;

var req = CTalk.getHTTPReq(); //get XMLHttpRequest or throw exception
if not supported
var reqStage1OK = false;

var to = setTimeout(function() { req.abort(); if(reqStage1OK)
CTalk.displayErrOnCon(CTalk._M_ERRCON_TYPE_INCOMPLETE); else
CUi.displayMsg("Error Connecting to X!",true); },
CTalk.respWaitASTol);

var url = "req.php?CID=" + escape(CTalk._M_CLIENT_ID) + "&M=" +
escape(mtype + param);
CUtil.log("opening ASync req: " + url);
req.open("GET", url, true);

req.onreadystatechange = function()
{
try
{
if(req)
{
CUtil.log("sendAsyncReq state : " + req.readyState);

if(req.readyState==1)
reqStage1OK = true;
else if(req.readyState==4)
{
if(req.status==200)
{
clearTimeout(to);
CUtil.log("HTTP 200 from sendAsyncReq, done.");
callback(req.responseText);
onExitRoot=true;
}
else
{
clearTimeout(to);
CUtil.log("HTTP/1.1 ERR from sendAsyncReq.");
try { CUi.displayMsg("Error",true); req.abort(); } catch(err) {}
onExitRoot=true;
}
}
}
} catch(e) { CUtil.log(e.message); alert("ERR: " + e.message); }
}

CUtil.log("About to send data request");
req.send(null);

if(onExitRoot && !callerHasLeft)
{
CUtil.log("Async not working!!");
//IF we get here async didn't work!!
//THis case is hit in IE6 on one call and then on a
subsiquent call it is not hit.
}

callerHasLeft = true;
} catch(e) { CUtil.log(e.message); alert("ERROR: " + e.message); }
 
S

Steve Swift

JT said:
This problem is sporadic, only happening on some peoples PCs some of
the time and not others (with the same full version as seen in
Help->About).

I don't know what you mean my "same full version" but mine says
6.0.2900.5512.xpsp.080413-2111

Since I received my PC a couple of years ago, Microsoft Update has
applied quite a few fixes affecting IE, and that version probably
doesn't identify exactly which combination I have.

Over this period, the behaviour of my IE6 has departed radically from
that of colleagues who don't run Microsoft/Windows update. The variation
is so great that two different IE6's, using the same CGI script, erase
different files when exactly the same button is clicked. (In later IE6,
only the button clicked gets submitted, so the correct file is deleted;
in earlier IE6, all of the delete buttons are submitted, so depending
how you wrote your CGI script, you either erase ALL possible files, or
the first, or the last. I was "lucky", and erased only the last, which
happened to be an extreme test case).

So don't expect all IE6's to behave the same, perhaps not even when
their version is the same.
 
T

Thomas 'PointedEars' Lahn

JT said:
Asynchronous JavaScript

There is no such thing to begin with. All known ECMAScript implementations
are single-threaded. window.setTimeout()/setInterval(), which can emulate
threads to a certain extent, are host-defined features that are not part of
any current JavaScript version (1.4+) and have never been part of JScript.
I am building a Web App which relies heavily on asynchronous
javascript (XMLHttpRequest).

It works a beautifully in IE7 and FF 2+ , but in IE6 (6.0.2900.2180
((sp2)) even though the asynchronous flag is set to true the call is
synchronous and doesn’t fork!!

That is your *assumption*. Your code shows that your assumption is at fault
here, not necessarily IE/MSHTML.
req.onreadystatechange = function()
{
try
{
if(req)
{
CUtil.log("sendAsyncReq state : " + req.readyState);

if(req.readyState==1)
reqStage1OK = true;
else if(req.readyState==4)
{
if(req.status==200)
{
clearTimeout(to);
CUtil.log("HTTP 200 from sendAsyncReq, done.");
callback(req.responseText);
onExitRoot=true;
}
else
{
clearTimeout(to);
CUtil.log("HTTP/1.1 ERR from sendAsyncReq.");
try { CUi.displayMsg("Error",true); req.abort(); } catch(err) {}
onExitRoot=true;
}
}
}
} catch(e) { CUtil.log(e.message); alert("ERR: " + e.message); }
}

CUtil.log("About to send data request");
req.send(null);

if(onExitRoot && !callerHasLeft)
{
CUtil.log("Async not working!!");
//IF we get here async didn't work!!
//THis case is hit in IE6 on one call and then on a
subsiquent call it is not hit.
}

There is the root of your mistake. You are assuming that when onExitRoot ==
true the event listener must have exited. But the nature of asynchronous
(request-response) handling is that things happen (here: seemingly) in
parallel, and that req.send(null) does _not_ wait for the listener to be
called. So it is entirely possible that the assignment did take place when
you evaluate the property value.

Since you always set `callerHasLeft' to `false' before req.send(null)
always, the second operand of the AND operation is always true and so does
not matter.


PointedEasrs
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top