0

I've looked at this questions, but I'm still stuck at this JavaScript closure inside loops – simple practical example

Here's my code

template[prop['Name']] = [];
var processedCounter = -1;
$.each(prop.Properties, function (key, value) {                    
  console.log(processedCounter + 'outside');
  $.getJSON(value['Url']).done(function (jsres) {
    console.log(processedCounter + 'inside');
    var numItems = jsres[itemCount].length;
    if (template[prop['Name']].length == 0) {
      console.log('this should only be printed once');
      for (var i = 0; i < numItems; i++) {
        template[prop['Name']].push({});
      }
    }                           
    processedCounter += 1;
  });                    
});

There's several issues. First it that it prints the message 'this should only be printed once' two times. Second is that the value of processedCounter has to be -1 instead of 0, because the value is increased at the wrong time.

iagowp
  • 2,428
  • 1
  • 21
  • 32
J. Margarine
  • 397
  • 1
  • 3
  • 8
  • 1
    The issue here is most likely a race condition. Your each is starting multiple getJSON requests very quickly (javascript runs very fast). So depending on how fast those requests finish, it is possible that both of them could be executing their done logic and get past the if conditional before either of them update the template element. – Taplar Nov 21 '18 at 14:37
  • 1
    The message that will only be printed once, will print once for each getJSON() call you make, which should be equal to the amount of props in prop.Properties. And the counter should log `-1 outside` twice. This is a good example why I use Promise.all() combined with urls.map( fetch( url ) ) to avoid situations like this. – Shilly Nov 21 '18 at 14:40
  • I ended up refactoring the code to do the whole thing in a different way and got it working – J. Margarine Nov 21 '18 at 14:54

0 Answers0