views:

163

answers:

3

I'm attempting to issue two concurrent AJAX requests.

The first call (/ajax_test1.php) takes a very long time to execute (5 seconds or so). The second call (/ajax_test2.php) takes a very short time to execute.

The behavior I'm seeing is that I /ajax_test2.php returns and the handler gets called (updateTwo()) with the contents from /ajax_test2.php.

Then, 5 seconds later, /ajax_test1.php returns and the handler gets called (updateOne()) *with the contents from /ajax_test2.php still!!!*

Why is this happening?

Code is here: http://208.81.124.11/~consolibyte/tmp/ajax.html

+8  A: 

This line:-

req = new XMLHttpRequest();

should be:-

var req = new XMLHttpRequest();
AnthonyWJones
Exactly. By leaving out var, req is an implied global and was being overwitten by the second AJAX call.
Zach
JavaScript's Worst Design Feature (and not without strong competition) strikes again.
bobince
@bobince - this has nothing to do with JS and everything to do with the author. The exact same effect is available in C# or any given language and sometimes it's what is required.
annakata
It's JavaScript's fault for making a simple assignment default to global (or nearest declaration scope), which is almost always not what you want and not what other languages do. For a language with many naive authors who don't understand scopes, this is a dangerous design decision.
bobince
@annakata: the same bug can not be repeated in C#. The problem is that javascript will dynamically add the req identifier to the global context during an assignment if it isn't found elsewhere in the scope chain. In C# the req identifier would have to already exist in scope which is not the same.
AnthonyWJones
+1  A: 

As AnthonyWJones stated, your javascript is declaring the second AJAX object which first overwrites the req variable (which is assumed global since there is no var) and you are also overwriting the ajax variable.

You should separate your code i.e:

function doOnChange()
{
 var ajax1 = new AJAX('ajax_test1.php', 'one', updateOne);
 var ajax2 = new AJAX('ajax_test2.php', 'two', updateTwo);
}
function AJAX(url, action, handler)
{
 if (typeof XMLHttpRequest == "undefined")
 {
  XMLHttpRequest = function()
  {
   try { return new ActiveXObject("Msxml2.XMLHTTP.6.0") } catch(e) {}
   try { return new ActiveXObject("Msxml2.XMLHTTP.3.0") } catch(e) {}
   try { return new ActiveXObject("Msxml2.XMLHTTP") } catch(e) {}
   try { return new ActiveXObject("Microsoft.XMLHTTP") } catch(e) {}
   throw new Error( "This browser does not support XMLHttpRequest." )
  };
 }

 url = url + '?action=' + action + '&rand=' + Math.random()

 var req = new XMLHttpRequest();
  req.onreadystatechange = function() {
    if (req.readyState == 4)
    {
     if (req.status == 200) 
     {
      alert('' + handler.name + '("' + req.responseText + '") ')
      handler(req.responseText)
     }
    }
   }

  req.open("GET", url, true);
  req.send(null);
}

Regards

Gavin

Gavin
A: 

Diodeus and Mike Robinson:

You guys didn't read my post fully. I know that one of the pages takes longer to execute than the other. That is the expected behavior of each page.

HOWEVER if you read my original post, the problem is that the callback for both pages ends up getting called with the HTML contents of the first page only.

AnthonyWJones and Gavin:

Thanks guys! That works like a charm! I guess I need to brush up on my Javascript!

Keith Palmer