dorukce
dorukce

Reputation: 77

Synchronous request with ajax in a loop

I have a for loop which contains ajax request. The request is working aynchronously. So i can't reach the result of request in time. How can i solve this problem without using any library? Thanks.

    var availables = document.getElementsByClassName("available");

    for(var i=0;i<availables.length;i++){
        var element = availables[i];

        var xmlhttp;
        if(window.XMLHttpRequest)
            xmlhttp = new XMLHttpRequest;
        else
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");

        xmlhttp.open("GET", "control.php?user=" + element.innerText, true);
        xmlhttp.send();

        xmlhttp.onreadystatechange = function(){
            if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
                var result = xmlhttp.responseText;
                console.log(result);

                element.setAttribute("class" , "result available " + result);
                if(result == "online")
                    element.innerHTML = "<a href=\"http://twitter.com/" + element.innerText + "\">" + element.innerText + "</a>";   
            }
        }
    }

Upvotes: 0

Views: 922

Answers (2)

Eugene Gluhotorenko
Eugene Gluhotorenko

Reputation: 3164

It is very bad practice to make your ajax calls synchronously xmlhttp.open("GET", "control.php?user=" + element.innerText, true) because you cannot interact with your application until an ajax request ends. I think in your case it is better to send every next request in the onreadystatechange callback of the previous one.

Upvotes: 0

Samuel Reid
Samuel Reid

Reputation: 1766

First of all, I'd suggest putting your xmlhttp.onreadystatechange function before you do xmlhttp.open and xmlhttp.send. It's possible that it's sending and returning and since it's running asynchronously, it's getting back before you're onreadystatechange function can be defined/executed. Something like that.

Anyway, you can always do it all synchronously by setting the last argument in xmlhttp.open to false. This will make javascript wait after xmlhttp.send before continuing, but either way you'll still need to put onreadystatechange before open and send.

    var availables = document.getElementsByClassName("available");

for(var i=0;i<availables.length;i++){
    var element = availables[i];

    var xmlhttp;
    if(window.XMLHttpRequest)
        xmlhttp = new XMLHttpRequest;
    else
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");

    xmlhttp.onreadystatechange = function(){
        if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
            var result = xmlhttp.responseText;
            console.log(result);

            element.setAttribute("class" , "result available " + result);
            if(result == "online")
                element.innerHTML = "<a href=\"http://twitter.com/" + element.innerText + "\">" + element.innerText + "</a>";   
        }
    }

    xmlhttp.open("GET", "control.php?user=" + element.innerText, true);
  //xmlhttp.open("GET", "control.php?user=" + element.innerText, false); //If you want to do it synchronously
    xmlhttp.send();
}

Upvotes: 2

Related Questions