json .get只作用于数组中的最后一个元素

时间:2015-10-05 21:24:12

标签: javascript jquery arrays

我正在尝试在Google地图上刷新我的标记图像。 我正在遍历标记数组并从服务器获取新信息。他们正在为数组中的每个标记获取正确的信息。但是当他们更新标记时,它是更新数组中的最后一个。

function refreshMarkerImages(markersArray){                                                                                                                                              

    for (index in markersArray){                                                                                                                                                                                                                                                                                                                                                      
        var markerObject = markersArray[index];                                                                                                                                              
        requestUrl = "/update_canvas_rain_pin_markers";                                                                                                                             
        requestParams = "rain_sensor=" + markerObject.rain_sensor_id;                                                                                                                        

        $.get(requestUrl, requestParams, function(response) {                                                                                                                                
            text  = response.split(",")[0];                                                                                                                                                  
            color = response.split(",")[1];                                                                                                                                                  
            markerObject.setMap(null);                                                                                                                                                       
            newImage = createMarkerCanvasIcon(text, color)                                                                                                                                   
            markerObject.setIcon(newImage);                                                                                                                                                  
            markerObject.setMap(map);                                                                                                                                                        
        })                                                                                                                                                                                 
    }    
}               

感谢您的任何提示。

2 个答案:

答案 0 :(得分:0)

这应该为你解决:

function refreshMarkerImages(markersArray) {
    for (index in markersArray) {

        (function (index) {//added closure index is now local to function
            var markerObject = markersArray[index];
            requestUrl = "/update_canvas_rain_pin_markers";
            requestParams = "rain_sensor=" + markerObject.rain_sensor_id;

            $.get(requestUrl, requestParams, function (response) {
                text = response.split(",")[0];
                color = response.split(",")[1];
                markerObject.setMap(null);
                newImage = createMarkerCanvasIcon(text, color)
                markerObject.setIcon(newImage);
                markerObject.setMap(map);
            });
        }(index))
    }
}

编辑,简短说明: 由于在调用内部函数时循环内部使用内部异步函数,循环已经结束运行,这就是它始终在最后一个索引上的原因。

我将代码包装在一个自调用函数中,该函数接收索引作为参数,并在调用括号中提供该索引。

这为每个调用创建了一个具有正确索引的执行上下文,因为索引现在是执行代码的一部分。

答案 1 :(得分:0)

我想如果您了解JIT(即时)编译器对您的代码所做的事情,您将更好地理解为什么会发生这种情况。

// These variables were never initialized with "var", so they are globally scoped.
var index, requestUrl, requestParams, text, color, newImage;

function refreshMarkerImages(markersArray) {
  var markerObject;

  for (index in markersArray) {
    markerObject = markersArray[index];
    requestUrl = "/update_canvas_rain_pin_markers";
    requestParams = "rain_sensor=" + markerObject.rain_sensor_id;

    $.get(requestUrl, requestParams, function(response) {
      text = response.split(",")[0];
      color = response.split(",")[1];
      markerObject.setMap(null);
      newImage = createMarkerCanvasIcon(text, color)
      markerObject.setIcon(newImage);
      markerObject.setMap(map);
    })
  }
}

你可以看到你期望在你的循环中的markerObject实际上被提升到范围的顶部,在这种情况下是函数。每个循环,它们都写在相同的变量上,所以无论谁最后运行,都会赢。

当您看到流程的工作方式时,您可以了解更多信息:

让我们说

markersArray = [ 0, 1, 2];

第一次打勾:

index = 0
markerObject = something0
requestUrl = something0
requestParams = something0
ajaxResponse0 = somerequest0
index = 1
markerObject = something1
requestUrl = something1
requestParams = something1
ajaxResponse0 = somerequest1
index = 2
markerObject = something2
requestUrl = something2
requestParams = something2
ajaxResponse0 = somerequest2

现在已完成所有同步代码,因此可能会发生以下滴答:

HandleAjaxResponse0; // markerObject === something2
HandleAjaxResponse1; // markerObject === something2
HandleAjaxResponse2; // markerObject === something2

请注意,您已使用同步代码更改了所有markerObject,因此您无法再访问所期望的值。

您需要做的是为循环的每次传递创建一个新变量,这样您就不会丢失您期望的值的上下文。你可以使用循环和闭包,也可以使用Array.prototype.map,这可能是一个更好的选择,因为它是它的用途:

function refreshMarkerImages(markersArray) {

  markersArray.map(function(markerObject) {
    var requestUrl = "/update_canvas_rain_pin_markers";
    var requestParams = "rain_sensor=" + markerObject.rain_sensor_id;

    $.get(requestUrl, requestParams, function(response) {
      var text = response.split(",")[0];
      var color = response.split(",")[1];
      markerObject.setMap(null);
      var newImage = createMarkerCanvasIcon(text, color)
      markerObject.setIcon(newImage);
      markerObject.setMap(map);
    })
  });

}