through jquery I check for a folder

for (var i=1;i<=100;i++){ $.post( "http://192.168.100.67/vtnuft/group"+i+"/check.php", function(response){ response = JSON.parse(response); $.each(response, function( key, val ) { if(key === "check" && val === true){ console.log(key,val,i); informationArray.push(i);} else if(key === "check" && val === false){ console.log(i,"false"); } }); }); } 

But in the informationArray, 101 are saved as many times as the PCP found with {{check '=> true}

What is the reason for this behavior?

  • The reason is that $ .post asynchronous operation - Grundy
  • @Grundy not, not in this - Pavel Mayorov
  • @PavelMayorov, in this in this, when the callback for the post is executed, the cycle is already completed and the value of i is 101 - Grundy
  • The @Grundy problem is common to the "closure + cycle" combination and is not related to asynchrony. - Pavel Mayorov
  • how to solve a problem without writing a post-method a hundred times - Mikola Kіkets

1 answer 1

The problem is that in each closure you use the same variable i - which changes. To keep the value of the variable unchanged - you need to create a new context by calling an anonymous function.

Here is one way:

 for (var i=1; i<=100; i++) !function(i) { // $.post(... и т.д. }(i); 

What kind of magic is going on here?

function(i) { ... } is the declaration of an anonymous function that takes a parameter i . This parameter hides the external variable i .

function(i) { ... }(i) is a call to the declared anonymous function, passing the value of the variable i as a parameter to it. Now inside the function, the parameter i is equal to the value that variable i at the time of the call. Now the cycle can go further, the value of the variable i will change to 101 - but inside the anonymous function the value of the parameter i will remain unchanged.

!function(i) { ... }(i) is one of the ways to write the last version so that the interpreter understands that this is an expression. The fact is that if a string starts with the word function , the interpreter will consider it a definition of a naming function, and there will be a syntax error. To avoid this, any operation is added to the expression.

The following design options are also allowed:

  • ~function(i) { ... }(i)
  • +function(i) { ... }(i)
  • -function(i) { ... }(i)
  • 1/function(i) { ... }(i)
  • (function(i) { ... })(i)
  • (function(i) { ... }(i))

Another option is to wrap in an anonymous function not the entire loop body, but only the callback function passed to $.post :

 for (var i=1; i<=100; i++) $.post("http://192.168.100.67/vtnuft/group"+i+"/check.php", function (i) { return function (responce) { // ... } }(i)) 

Here the anonymous function is not at the very beginning of the line - and therefore no tricks are required. Choose the one you like.

  • I think it was easier to return the group number from the server :-D - Grundy
  • great answer. In order not to disappear, please restate the title of the question of the TS (and the body of the question, ideally), so that it can be easily found with a similar problem. The current wording “checking for a folder” is completely misleading. - Sergiks