最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

javascript - Ajax Request is blocking - Stack Overflow

matteradmin4PV0评论

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); 
Post a comment

comment list (0)

  1. No comments so far