我正在尝试在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);
})
}
}
感谢您的任何提示。
答案 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);
})
});
}