-1

I find it weird that I get this output:

Wait..
Request 2 Complete.
Request 2 Complete.

On a simple for loop:

for (var i = 0, j = urls.length; i < j; i += 1) {
    $.ajax({
        url: urls[i],
        dataType: 'jsonp',
        complete: function() {
            log.append('Request ' + i + ' Complete.' + "\n");
            if (i == (j - 1)) {
                log.append('Done.');
            }
        }
    });

}

How come i is always equal to 2?

1
  • 2
    The problem occurs because the closure closes over the variable i, not its value when the closure was created. Many languages other than JavaScript exhibit this issue, including C# and Visual Basic. Do a search for "access to modified closure" if you want more background on this extremely common error. Commented Jan 6, 2013 at 14:02

2 Answers 2

5

This is, because both calls to i inside your ajax request reference the same i of the for-loop. At the point in time, when the requests are completed (and thus i is accessed) the loop has terminated and i has the final value, here 2.

I think you look for something like this:

for (var i = 0, j = urls.length; i < j; i += 1) {
  !function( i ){
    $.ajax({
        url: urls[i],
        dataType: 'jsonp',
        complete: function() {
            log.append('Request ' + i + ' Complete.' + "\n");
            if (i == (j - 1)) {
                log.append('Done.');
            }
        }
    });
  }( i );
}

By passing the value of i to the immediately executed function, you create a copy of the respective value of i to use inside the ajax-requests.

Sign up to request clarification or add additional context in comments.

3 Comments

Hi sir, what terminology is this technique called? I'd like to know more about it. Thanks BTW.
@Hermione In general this is a problem of scope and closure in JavaScript. See, e.g., this question. If there is a specific name for the technique I used, I don't know it, though.
@WearetheWorld No it won't. But each request will have an unique id, which is in the same order as the requests are started. So if you have to do any synchronization of the results, you can use that id.
0

try using

     async = false;
in ajax request

1 Comment

That would solve the problem with the value of i but the site would be much slower. Sirkos solution is the better approach.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.