防止Google地方信息请求中的过多递归

时间:2017-10-23 08:16:07

标签: javascript google-maps recursion google-places-api

我目前正在创建一个接收来源,目的地和距离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个。编辑:这可能会使递归堆栈大小保持在合理的大小。

0 个答案:

没有答案