等待循环完成之前在javascript中传递值(也是谷歌地图)。
问题描述:
我不使用JavaScript太多,所以我不熟悉回调和响应。我使用谷歌地图来绘制A点和X,Y,Z点之间的距离。值得注意的是,我想用javascript来确定哪个点X,Y,Z最接近A,并且它们会映射它们之间的方向。等待循环完成之前在javascript中传递值(也是谷歌地图)。
我的代码正在工作。我可以计算出所有3个目的地的最短距离,但我被这个愚蠢的目光困住了。
您会发现,Google使用异步回调向浏览器提供数据,如果我运行for循环来逐个检查所有3个目标,我会得到不正确的结果。
下面是代码:
var maxDistance = 99999999999;
var destn;
for (var i = 0; i < locations.length; i++) {
var thisDistance = 0;
var start = origin;
var end = locations[i];
var request = {
origin: start,
destination: end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
thisDistance = response.routes[0].legs[0].distance.value;
if (thisDistance < maxDistance) {
destn = response.routes[0].legs[0].end_address;
maxDistance = thisDistance;
}
} else {
document.getElementById("addressNotFound").style.display = 'block';
}
});
}
calcShortestRoute(origin, destn);
所以,很显然,当我调用这个函数,纸位置的值出现,因为循环结束与谷歌处理程序处理不当接收到的数据却是不确定的。如果我再次调用函数1,我会得到从前一个回调(之前未定义)接收到的destn值。
有人请告诉我如何解决这个问题。
答
您需要等到所有三个Google回复都已返回。一个简单的解决方案是:将你距离计算函数调用到末尾的匿名函数,然后calc下的距离只有当所有响应都返回:
// global count variable
var callbackCount = 0;
for (var i = 0; i<locations.length; i++) {
var thisDistance=0;
var start = origin;
var end = locations[i];
var request = {
origin:start,
destination:end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
thisDistance = response.routes[0].legs[0].distance.value;
if (thisDistance < maxDistance) {
destn = response.routes[0].legs[0].end_address;
maxDistance = thisDistance;
}
}
else {
document.getElementById("addressNotFound").style.display = 'block';
}
// move this to here, and pass in number of locations
calcShortestRoute(origin, destn, locations.length);
});
}
然后calcShortestRoute样子:
function calcShortestRoute(origin, destn, locationCount) {
// increment callback count
callbackCount++;
if (callbackCount == locationCount) { // all responses have returned
// do your distance checking
....
}
}
答
当你退出的循环,因为它被设置异步你directionsService.route()
收到您的结果后,您不会有destn
值。相反,你需要跟踪的多少请求返回,并调用你的函数从响应回调中,你已经收到所有的答复之后:
... // your code
var responseCount = 0;
for (var i = 0; i < locations.length; i++) {
... // your code
directionsService.route(request, function(response, status) {
... // your code
if (++responseCount == locations.length) {
calcShortestRoute(origin, destn);
}
});
}
编辑:我重读你的问题,并认为我更好地理解你的代码在做什么。这个答案应该更准确(并且更加简洁,可以启动!)。
' calcShortestRoute''''''''''''''''''''''''''''将始终通过''''完成',因为'''将永远是'请参阅http://jsfiddle.net/gilly3/9526m进行简单演示。即使它按照你想要的那样工作,它仍然无法工作。异步调用可以按任意顺序返回。所以,仅仅因为最后的请求已经返回,并不意味着所有的请求都返回了。 – gilly3 2011-04-13 22:26:06
@ gilly3 - 是的,当然,回应可能不会返回顺序:)我已经修改我的回答 – 2011-04-14 11:46:26
真棒。这工作得很好。谢谢Rich。 – 2011-04-14 14:24:43