Google Maps API - 每秒限制超过QUERY LIMIT

时间:2017-11-06 17:49:34

标签: javascript google-chrome google-maps-api-3

我正在使用Google Maps API显示20个地点的列表以及到达目的地的时间。我使用的是google.maps.DirectionsService。这个API每秒限制设置为10个调用,如果我只有10个位置,我可以同时调用所有(测试并且它完美地工作)。当我有超过10个位置时,我正在使用呼叫块进行呼叫。例如,有16个位置:我呼叫前10个位置,然后我等待 3秒并呼叫其他6个位置。

理论上,这种方法应该有效,因为我尊重每秒10次的限制。 但是,不起作用。当我尝试呼叫其余6个位置时,我收到错误OVER_QUERY_LIMIT,有时其中4个失败,有时3个失败。如果我将等待时间增加到5秒,有时候工作正常,有时其中一个会失败。

问题:这个限制不应该是每秒10次查询吗?如果是,那么我可能做错了什么?以及如何解决它?

//------------------ Code ----------------

getDistanceByBlocks(destinations: IDestination[]){
    let limit = 8;
    if(destinations.length <= limit){
        destinations.forEach(destination => {
            this.getDistance(destination);
        }); 
    }else{
        let selection = destinations.slice(0, limit)
        let rest = destinations.slice(limit)
        selection.forEach(destination => {
            this.getDistance(destination);
        });
        setTimeout(() => {
            this.getDistanceByBlocks(rest)
        },3000);
    }
}

getDistance(destination: IDestination) {
    if (this.dataService.getCurrentLocation()) {
        let mapSettings = this.userSettings.getMapSettingsSync();
        this.mapService.getRoutes(destination, mapSettings);
    }
}

//------------------ MapService----------------

getRoutes(destination: IDestination, mapSettings:IMapSettings): void {
    let directionsService = new google.maps.DirectionsService;
    this.currentLocation = this.dataService.getCurrentLocation();

    directionsService.route(
    {   
        origin: { lat: this.currentLocation.latitude, 
        lng: this.currentLocation.longitude },
        destination: { lat: destination.latitude, lng: destination.longitude },
        provideRouteAlternatives: mapSettings.provideRouteAlternatives,
        avoidHighways: mapSettings.avoidHighways,
        avoidTolls: mapSettings.avoidTolls,
        drivingOptions: {
            departureTime: new Date(Date.now()),
            trafficModel: mapSettings.trafficModel
        },
        travelMode: google.maps.DirectionsTravelMode.DRIVING,
        unitSystem: google.maps.UnitSystem.IMPERIAL
    }, 
    (response, status) => {
        if (status == google.maps.DirectionsStatus.OK) {
            let routes: IRouteInfo[] = response.routes
                .map(route => {
                    let routeInfo: IRouteInfo = {
                        summary: route.summary,
                        distance: route.legs[0].distance.text,
                        timeValue: route.legs[0].duration.text,
                    };
                    return routeInfo;
                });
            destination.routes = routes;
            this.events.publish(AppSettings.UPDATE_DESTINATIONS)

       } else if (status == google.maps.DirectionsStatus.OVER_QUERY_LIMIT){
            console.warn(status);
       } else {
            console.warn(status);
       }
   });
}

请务必注意,在Chrome网络标签中,我们可以看到每次通话之间的等待时间以及我遇到的错误数量。令我很感兴趣的是,我没有看到失败的电话,Chrome没有向我显示。所以我认为google.maps服务是在javascript中处理它并且它没有调用服务器,但实际上我还没有线索。

Chrome Network Tab Example

1 个答案:

答案 0 :(得分:1)

我的一个项目遇到了同样的问题。我想你必须在每个请求之间保持一段时间。像这样,服务器不断收费。对于我的项目,我使用此代码:

private Configuration configureMeanBeanTests() {
    URLFactory urlFactory = new URLFactory();
    return new ConfigurationBuilder()
        .overrideFactory("demoUrl", urlFactory).build();
}

@Test
public void testAccessors() {
    new BeanTester().testBean(Product.class, configureMeanBeanTests());
}

@Test
public void testEquals() {
    new EqualsMethodTester().testEqualsMethod(
        Product.class,
        configureMeanBeanTests(),
        "name",
        "demoUrl"
    );
}

@Test
public void testHashCode() {
    new HashCodeMethodTester().testHashCodeMethod(Product.class);
}

在这里,我定义了请求并发送了它。请注意,我在每个请求之间给出0.3秒的时间。

您还可以使用此代码以了解何时出现OVER_QUERY_LIMIT错误:

for (var i = 0; i<6; i++) {
    (function (i) {
     setTimeout(function () {
        var service = new google.maps.places.PlacesService(map);
        var request = {
            placeId: yourArray [i]
        };

        service.getDetails(request, callback);
    }, i * 300);
    })(i);
}

如果您有任何问题或意见,请告诉我。