After spending some time learning JavaScript, I recently delved into AJAX and encountered something unusual that caught my attention.
Consider this sample code snippet:
var receiveReq = XMLHttpRequest();
//Initialize the asynchronous request.
function sayHello() {
//Check if our XMLHttpRequest object is not in the middle of another request, then start a new asynchronous call.
if (receiveReq.readyState == 4 || receiveReq.readyState == 0) {
//Set up the connection for a GET call to SayHello.html. The true value explicitly sets the request as asynchronous.
receiveReq.open("GET", 'SayHello.html', true);
//Define the function to handle state changes in the XMLHttpRequest object.
receiveReq.onreadystatechange = handleSayHello;
//Make the actual request.
receiveReq.send(null);
}
}
function handleSayHello() {
//Verify if the XmlHttpRequest's state indicates completion.
if (receiveReq.readyState == 4) {
//Update the content of the span element with the result of the asynchronous call.
document.getElementById('span_result').innerHTML = receiveReq.responseText;
}
}
When executing this function, it seems like the browser repeatedly invokes handleSayHello(). This behavior puzzles me because I have never seen anything like this in JavaScript or any other language. How does this mechanism operate, and are there similar features in JavaScript?
Moreover, what would occur if receiveReq.readyState
was neither 0 nor 4 when the if statement in sayHello()
is triggered?
Edit:
I made a slight adjustment to the sayHello()
function, resulting in the following update:
function sayHello() {
//Initiate a new asynchronous call only if our XmlHttpRequest object is not already processing a request.
if (receiveReq.readyState == 4) {
receiveReq.open("GET", 'SayHello.html', true);
receiveReq.onreadystatechange = handleSayHello;
receiveReq.send(null);
}
else
alert("readyState = " + receiveReq.readyState);
}
To my surprise, this refined code snippet still functions properly. What struck me is that this if statement executes twice: once when readyState equals 0, and again when readyState equals 4. How did this dual execution occur?
Below is the complete source code:
<html>
<head>
<title>The Hello World of AJAX</title>
<script language="JavaScript" type="text/javascript">
function getXmlHttpRequestObject() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
} else if(window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
} else {
alert("Your browser doesn't support the XmlHttpRequest object. Please consider upgrading to Firefox.");
}
}
var receiveReq = getXmlHttpRequestObject();
function sayHello() {
if (receiveReq.readyState == 4 || receiveReq.readyState == 0) {
receiveReq.open("GET", 'SayHello.html', true);
receiveReq.onreadystatechange = handleSayHello;
receiveReq.send(null);
}
}
function handleSayHello() {
if (receiveReq.readyState == 4) {
document.getElementById('span_result').innerHTML = receiveReq.responseText;
}
}
</script>
</head>
<body>
<a href="javascript:sayHello();">Say Hello</a><br />
<span id="span_result"></span>
</body>
</html>
The content inside SayHello.html simply says:
hello, world