Function call inside loop taking only last iteration

五迷三道 提交于 2019-12-22 18:33:30

问题


my code look like this:

if (ACTIVETICKETS.length > 0) 
{
    for (var m in  ACTIVETICKETS) 
    {
        if (ACTIVETICKETS.hasOwnProperty(m)) 
        {
            var marker = new L.Marker(new L.LatLng(ACTIVETICKETS[m].location.x, ACTIVETICKETS[m].location.y));
            createHtmlForPopUp(m, function(data)
            {
                console.log(m);
                marker.bindPopup( data ); // calling a function with callback
                tile_layer.addLayer(marker);                           
            });
        }
    } // for loop ends here
}

While executing this, I am getting only the last iteration of m. Total length of ACTIVETICKETS array is 16. So I am getting only 15 entered 16 time


回答1:


The code below should work, but as I commented above, please read about closure so you know why.

    if (ACTIVETICKETS.length > 0) {
      for (var m in  ACTIVETICKETS) {
        (function(x) {
          if (ACTIVETICKETS.hasOwnProperty(x)) {
            var marker = new L.Marker(new L.LatLng(ACTIVETICKETS[x].location.x, ACTIVETICKETS[x].location.y));
              createHtmlForPopUp(x, function(data){
                console.log(x);
                marker.bindPopup( data ); // calling a function with callback
                tile_layer.addLayer(marker);
              });
          }
        })(m);
      } // for loop ends here
    }



回答2:


The problem you have is that the value of m, by the time the callback is called, it the one of end of loop. A solution is to protect this value by setting it as value of a variable in an immediately called function :

for (var m in  ACTIVETICKETS) {
   (function(m){
        if (ACTIVETICKETS.hasOwnProperty(m)) 
        {
            var marker = new L.Marker(new L.LatLng(ACTIVETICKETS[m].location.x, ACTIVETICKETS[m].location.y));
            createHtmlForPopUp(m, function(data)
            {
                console.log(m);
                marker.bindPopup( data ); // calling a function with callback
                tile_layer.addLayer(marker);                           
            });
        }
    })(m);
 } // for loop ends here

This is because JavaScript doesn't have block scope, and only creates a new variable scope when a function is invoked.

You can use the same technique with a named function instead of an inline one as above:

function makeTicket(m){
  if (ACTIVETICKETS.hasOwnProperty(m)) 
  {
        var marker = new L.Marker(new L.LatLng(ACTIVETICKETS[m].location.x, ACTIVETICKETS[m].location.y));
        createHtmlForPopUp(m, function(data)
        {
            console.log(m);
            marker.bindPopup( data ); // calling a function with callback
            tile_layer.addLayer(marker);                           
        });
    }
}

Then do this:

for (var m in  ACTIVETICKETS) {
    makeTicket(m)
} // for loop ends here

And as a side note, there are very compelling reasons to not use a for-in enumeration on Arrays, but rather to use a typical for loop, and you don't need the outside if test, so you could remove it and just do

for (var m =0; m<ACTIVETICKETS.length; m++) {
    makeTicket(m)
}



回答3:


You need to create a closure over all the variables you want to access in the callback function.

    createHtmlForPopUp(m, (function (m, data, marker) {
        return function(data)

        {
            console.log(m);
            marker.bindPopup( data ); // calling a function with callback
            tile_layer.addLayer(marker);                           
        }
    })(m, data, marker));


来源:https://stackoverflow.com/questions/17491718/function-call-inside-loop-taking-only-last-iteration

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!