我目前正在创建一个接收来源,目的地和距离d
的应用程序,并返回距离源和目的地之间的路线最多d
距离的餐馆列表
我首先向DirectionsService.route()
发出请求以获取折线坐标。然后,我将每个坐标传递给radarSearch()
,以获得距离相应坐标place_id
距离的每个餐厅的d
。
收到place_id
后,我将其传递给getDetails()
以获取详细信息。
如果路线足够小并且距离足够小,则上述过程可以正常工作。但是在增加两者中的任何一个时,递归循环超过了Chrome和Firefox的最大限制。
这是我的代码 -
button.addEventListener("click", function() {
distance = document.getElementById('distance').value/1000; // distance is in kms
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer();
directionsDisplay.setMap(map_directions);
directionsDisplay.setPanel(document.getElementById('panel'));
var request = {
origin: document.getElementById('source').value,
destination: document.getElementById('destination').value,
travelMode: 'DRIVING'
};
directionsService.route(request, function(response, status) {
if (status == 'OK'){
directionsDisplay.setDirections(response);
for (i=0; i<response.routes[0].overview_path.length; i++) {
polyline_coordinates.push([response.routes[0].overview_path[i].lat(), response.routes[0].overview_path[i].lng()]);
}
findRestaurants(0);
}
else {
alert('Directions request failed');
}
});
});
findRestaurants()
获取与每个坐标place_id
距离的餐馆的d
s。如果我没有得到OVER_QUERY_LIMIT
,我会查询下一组坐标,否则,我等待1 second
。我还有一个Set()
- place_ids
- 来检查我是否有一家餐厅。
function findRestaurants(searchIndex) {
var curr_coords = new google.maps.LatLng(polyline_coordinates[searchIndex][0],polyline_coordinates[searchIndex][1]);
var request = {location: curr_coords,
radius: distance*1000,
type: 'restaurant'};
service.radarSearch(request, function(results, status) {
if (results != null) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i=0; i < results.length; i++) {
if (!place_ids.has(results[i].place_id)) {
place_ids.add(results[i].place_id);
restaurants.push(results[i]);
addMarker(results[i]);
}
}
}
}
if (status != google.maps.places.PlacesServiceStatus.OVER_QUERY_LIMIT) {
searchIndex++;
if (searchIndex < polyline_coordinates.length)
findRestaurants(searchIndex);
else {
// All coordinates have finished being queried. Now get details of restaurants
getRestaurantDetails(0);
}
}
else {
setTimeout(findRestaurants(searchIndex), 1000);
}
});
}
getRestaurantDetails()
然后使用getDetails()
查询每个place_id
以获取详细信息。 checkforAuthenticity()
检查返回的餐厅详细信息是否至少包含地址,电话号码和一些照片。逻辑与findRestaurants()
几乎相同;如果我收到1 second
,我等待OVER_QUERY_LIMIT
,否则我会查询下一个place_id
。
function getRestaurantDetails(index) {
service.getDetails(restaurants[index], function(result, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
if (checkForAuthenticity(result)) {
var curr_urls = [];
for (var j=0; j<result.photos.length; j++) {
curr_urls.push(result.photos[j].getUrl({ 'maxWidth': 1600, 'maxHeight': 1600 }));
}
result['photo_urls'] = curr_urls;
authentic_restaurants.push(result);
}
else {
markers[index].setMap(null);
}
}
if (status != google.maps.places.PlacesServiceStatus.OVER_QUERY_LIMIT) {
index++;
if (index < restaurants.length)
getRestaurantDetails(index);
else {
console.log("details done");
sessionStorage.setItem("authentic_unique", JSON.stringify(authentic_restaurants));
return;
}
}
else {
console.log('overshoot for details');
setTimeout(getRestaurantDetails(index), 1000);
}
});
}
正如我所说,上述代码适用于小距离和小路径。如果两个参数中的任何一个太高,浏览器都会抛出一个递归错误。 (我尝试了一条长20公里,距离100米的路线。)
有什么方法可以缓解这种情况吗?我尝试设置一些限制,直到每个递归函数都去,像这样 -
total_restaurants = restaurants.length;
curr_start = 0;
curr_limit = 50;
while (curr_limit<=total_restaurants) {
getRestaurantDetails(curr_start, curr_limit);
curr_start += curr_limit+1;
curr_limit += 50;
}
但我猜它基本上做同样的事情。因为它们都是Google Places API
的异步调用,所以递归堆栈会像以前一样增加。我最喜欢的是查询前50个coordindates / place_ids的某种方法,然后在前50个完成后查询下50个。编辑:这可能会使递归堆栈大小保持在合理的大小。