Reputation: 6168
I have a function to perform Ajax requests with a server. The code works but for some reason is blocking the rest of js code. So I have to wait until the request is over. This is really strange as ajax is asynchronous in nature. Any help will be appreciated.
Here's the code
function initRequest(url)
{
var xmlhttp = null;
if(xmlhttp != null)
{
if(xmlhttp.abort)
xmlhttp.abort();
xmlhttp = null;
};
if(window.XMLHttpRequest) // good browsers
xmlhttp=new XMLHttpRequest();
else if(window.ActiveXObject) // IE
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
if(xmlhttp == null)
return null;
xmlhttp.open("GET",url,false);
xmlhttp.send(null);
if(xmlhttp.status >= 200 && xmlhttp.status < 300)// 2xx is good enough
return xmlhttp.responseText.split("|");
else
return null;
}
and I call this function like this var res = initRequest('someurl'); if(res) { console.log(res); } console.log('this message will appear when the request is served!! WHY??');
Upvotes: 1
Views: 4766
Reputation: 8387
Please change the ajax request from synchronous
to asynchronous
and try like ,
From ,
xmlhttp.open("GET",url,false);
To ,
xmlhttp.onreadystatechange = function () {
if(this.status >= 200 && this.status < 300) {// 2xx is good enough
}
}
xmlhttp.open("GET",url,true);
Upvotes: 1
Reputation: 5841
The third parameter in xmlhttp.open("GET",url,false);
is whether or not to send the request asynchronously. Since you put false, it will run synchronously, which is why it blocks your code.
In order to make this asynchronous, you should change the third parameter to true
and then add assign a function to xmlhttp.onreadystatechange
that will be a callback for the async request (do this before you call .send()
.
Another important thing to consider is that since this is asynchronous, you don't want to return a value from your ajax request, as you'll have something waiting for that return value, which means it either won't get the return value, or you have to block everything and we're back to the original problem. So consider what it is that you want to "do" with ajax response. You can either directly code this into whatever you assign to xmlhttp.onreadystatechange
, or alternatively you can pass a callback into it using a closure, e.g.
function initRequest(url, callback)
{
...
xmlhttp.open("GET",url,true);
xmlhttp.onreadystatechange = (function(cb) {
return function() {
if(xmlhttp.status >= 200 && xmlhttp.status < 300)// 2xx is good enough
{
cb(xmlhttp.responseText.split("|"));
}
};
)(callback);
xmlhttp.send(null);
}
Then wherever you're calling initRequest
, define a function that will do something with the result, and then pass it in as the second parameter, e.g.
var logResult = function(result) {
console.log(result);
};
initRequest("page.php", logResult);
Let me know if this makes sense, or if you have any questions :)
Upvotes: 1
Reputation: 1800
You should implement the onreadystatechange callback on the XMLHttpRequest object and check for status changes in there, instead of waiting blockingly for the response of your server. This method is going to be called for each change of the readyStatus property and will (hopefully) return 200 at some point, after you called xmlhttp.send(...);
Edit: So your code would look like
function initRequest(url, onsuccess, onerror) {
// ...
xmlhttp.onreadystatechange = function () {
if(this.status >= 200 && this.status < 300) {// 2xx is good enough
onsuccess(this.responseText.split("|"));
}
};
xmlhttp.open("GET", url); // its asynchronous by default
xmlhttp.send(null);
}
For good measure some helpful links http://www.w3.org/TR/XMLHttpRequest1/ and https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
Upvotes: 3