Why is the incrementer "lost" in the loop?

Asked

Viewed 189 times

9

Making a simple loop FOR, I found a strange behavior that I couldn’t understand.

The count is "lost" in the AJAX request, keeping the value of the incrementer with the last one. The request to the URL always returns 200 and yet does not influence anything for the correct execution.

There is something related to the variable scope?

for (i = 0; i < 60; i++) {

  console.log("For:" + i);

  var urlMapas = "http://servicomapas.ibge.gov.br/api/mapas/" + i + '/1';

  $.ajax({
    url: urlMapas,
    dataType: "json",
    success: function(data) {
      console.log("AJAX:" + i);

    }
  });
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

  • I tested your code and the variable is incremented one by one until it reaches 60. I tested with the Chrome console.

  • 1

    Eduardo, did you check the variable inside AJAX? The outside of the request is counted normally but the inside is not.

  • 2

    See if this helps: http://answall.com/questions/1859/howit works

  • 1

    I understand what you want to do. If you give a console.log in the variable data, you will see that requests for each URL are being returned. If you want a loop within .success() will have to create another be, because it is a callback.

1 answer

8


It doesn’t get lost, it does exactly what it was told to do. The loop is one thing and the function passed to jQuery is another completely separate. This is because the function is a closure. It captures the variable, but not its state. So only the final state is considered.

As can be observed in the console the loop counts from 0 to 60 perfectly and the i this value when it closes.

The solution is to create a function and pass the loop variable as parameter to this function. And this function is what should call AJAX.

for (var i = 0; i < 60; i++) {
    console.log("For:" + i);
    (function(p) {
        $.ajax({
            url: "http://servicomapas.ibge.gov.br/api/mapas/" + p + '/1',
            dataType: "json",
            success: function(data) {
                console.log("AJAX:" + p);
            }
        });
    })(i);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

I put in the Github for future reference.

That’s why I say closure should only be used as a last resort, when the person knows all the consequences of it. jQuery abuses closures.

  • Roger, @bigown. The link passed by Pablo also gave a clear.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.