2013-07-05 39 views
2

我的代碼如下所示:函數調用只取最後一次迭代

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 
} 

在執行這個,我只得到m的最後一次迭代。 ACTIVETICKETS陣列的總長度爲16。所以,我只得到了15進16時

+0

好的,這是一個經典問題,讓我們只是尋找另一個相同的問題來關閉這個問題。 –

+0

在此期間阿克巴爾阿里,查找了關閉的概念。 –

+0

你的函數只能在循環結束後運行。 – Hogan

回答

2

下面的代碼應該工作,但就像我上面的評論,請閱讀closure,所以你知道爲什麼

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 
    } 
1

您遇到的問題是,在調用回調的時候,m的值就是循環結束的那個值。一種解決方案是通過在立即調用的函數設置它作爲一個變量的值來保護這個值:

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 

這是因爲JavaScript沒有塊範圍,並且僅創建一個新的變量範圍的函數時調用。

您可以使用相同的技術與上面命名函數而不是內嵌一個:

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);       
     }); 
    } 
} 

那麼做到這一點:

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

而作爲一個側面說明,有是非常有說服力的理由,因爲不在數組上使用枚舉,而是使用典型的for循環,並且如果測試不需要外部,那麼您可以刪除它並僅執行

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

您需要在回調函數中創建要訪問的所有變量的閉包。

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)); 
相關問題