Ajax无法在循环中工作[重复]

This question already has an answer here:

I want to execute Ajax in a loop to fetch data one by one. I did something like this in my javascript function.

var resultType = $("input[name='resultType']:checked").val();
var finalResult = "";
var loadingMessage = "<img src=\"./results/loader.gif\" alt=\"Loading...\"/><br/>This may take several minutes...";
var htmlMessage=loadingMessage;

$("#result").html(htmlMessage);

for(var i=1;i<5;i++){
    $.ajax({
        type: "GET",
        url: "results/result_html.php?usn="+i+"&resultType="+resultType,
        dataType:"JSON",
        success:function(result){
            finalResult+=result;
            result=result+htmlMessage;
            $("#info").hide();
            $("#result").html(result);              
            $("#usn").attr("placeholder", "Class USN");
        }
    });
}

But it is not executing as I expected. If I remove for loop and give value directly then everything is proper. I'm not much familiar with Ajax. Please can anyone help me?

</div>

you are dealing with a common problem with closures. by the time your ajax request is executed, the counter "i" is already and always at it's last value (4).

you have to create a new scope for that counter, so that it doesn't happen; you can do it in two ways:

the easy way:

for(var i=1;i<5;i++){
    var counter = i;
    $.ajax({
        type: "GET",
        url: "results/result_html.php?usn="+counter+"&resultType="+resultType,
        dataType:"JSON",
        success:function(result){
            finalResult+=result;
            result=result+htmlMessage;
            $("#info").hide();
            $("#result").html(result);              
            $("#usn").attr("placeholder", "Class USN");
        }
    });
}

or the correct way:

for(var i=1;i<5;i++){
(function(counter){
    $.ajax({
        type: "GET",
        url: "results/result_html.php?usn="+"counter"+"&resultType="+resultType,
        dataType:"JSON",
        success:function(result){
            finalResult+=result;
            result=result+htmlMessage;
            $("#info").hide();
            $("#result").html(result);              
            $("#usn").attr("placeholder", "Class USN");
        }
    });
})(i);}

I don't see a problem with closures in this code. I believe that what you are trying to achieve has to do with forcing a sequential load. The way you are currently proposing will issue all the ajax calls 'in parallel'. The problem relies in the asynchronous nature of an ajax call.

If you want to 'sequentialize' the requests, then you can do something like this:

var resultType =$("input[name='resultType']:checked").val();
var finalResult="";
var loadingMessage="<img src=\"./results/loader.gif\" alt=\"Loading...\"/><br/>This may   take several minutes...";
var htmlMessage=loadingMessage;
$("#result").html(htmlMessage);

var i = 1;

function loadNext(){
    if (i < 5){
        $.ajax({
            type: "GET",
            url: "results/result_html.php?usn="+i+"&resultType="+resultType,
            dataType:"JSON",
            success:function(result){
                finalResult+=result;
                result=result+htmlMessage;
                $("#info").hide();
                $("#result").html(result);              
                $("#usn").attr("placeholder", "Class USN");
                loadNext();
            }
        });
        i++;
    }
}