admin管理员组

文章数量:1025491

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??');

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??');

Share Improve this question asked Sep 18, 2013 at 6:26 Jabran SaeedJabran Saeed 6,1984 gold badges23 silver badges38 bronze badges 1
  • 4 XMLHttpRequest.open(method, url [, async = true [, user = null [, password = null]]]) – Andreas Commented Sep 18, 2013 at 6:31
Add a ment  | 

3 Answers 3

Reset to default 3

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/TR/XMLHttpRequest1/ and https://developer.mozilla/en-US/docs/Web/API/XMLHttpRequest

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 :)

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); 

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??');

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??');

Share Improve this question asked Sep 18, 2013 at 6:26 Jabran SaeedJabran Saeed 6,1984 gold badges23 silver badges38 bronze badges 1
  • 4 XMLHttpRequest.open(method, url [, async = true [, user = null [, password = null]]]) – Andreas Commented Sep 18, 2013 at 6:31
Add a ment  | 

3 Answers 3

Reset to default 3

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/TR/XMLHttpRequest1/ and https://developer.mozilla/en-US/docs/Web/API/XMLHttpRequest

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 :)

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); 

本文标签: javascriptAjax Request is blockingStack Overflow