Jabran Saeed
Jabran Saeed

Reputation: 6168

Ajax Request is blocking

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

Answers (3)

Human Being
Human Being

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

asifrc
asifrc

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

moxn
moxn

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

Related Questions