You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Maps JavaScript API V3多路线展示请求超限问题求助

解决Google Maps Directions API的OVER_QUERY_LIMIT问题

我明白你遇到的麻烦——当路线数量超过10条时就触发请求限制,而且之前的超时设置没起作用。先看看你当前代码里的关键问题:

  • 你在forEach里用setTimeout(calcRoute(...), 100)的时候,直接执行了calcRoute函数,而不是把它作为回调传给setTimeout。这导致所有请求几乎同时发送,完全没达到延迟的效果。
  • 没有处理OVER_QUERY_LIMIT状态的重试逻辑,Google API希望遇到这个状态时,能延迟一段时间后重试(最好用指数退避)。
  • 还有个小问题:你设置的地图中心是芝加哥的坐标,不是巴塞尔的,这会导致地图显示区域不对。

下面是修改后的可行方案,核心是按顺序逐个发起请求,加上延迟控制,同时处理重试:

<!DOCTYPE html> 
<html> 
<head> 
  <title>Display multiple routes</title> 
  <meta name="viewport" content="initial-scale=1.0"> 
  <meta charset="utf-8"> 
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> 
  <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&key=ENTER_API_KEY"></script> 
  <style> 
    /* Always set the map height explicitly to define the size of the div element that contains the map. */ 
    #map { height: 100%; } 
    /* Optional: Makes the sample page fill the window. */ 
    html, body { height: 100%; margin: 0; padding: 0; } 
  </style> 
</head> 
<body> 
  <div id="map"></div> 
  <script> 
    var addresses = [ 
      ['243, Dornacherstrasse', '26, Mattenstrasse'],
      ['48 av general de gaulle, saint louis', 'Gründenstraße 40, Muttenz'],
      ['50 ackerstrasse , Basel', 'holeestrasse 133, Basel'],
      ['71 avenue de Bâle , Saint-Louis ', 'Leonhardstr 6, Basel'],
      ['Ackerstrasse 44, Basel', 'Petersplatz 1, Basel'],
      ['Ackerstrasse 51, Basel', 'Maiengasse 51, Basel '],
      ['Aeussere Baselstr. 255, Riehen', 'zu den drei Linden 80, Basel'],
      ['Aeussere Baselstrasse 309, Riehen', 'Gotthelfplatz 1, Basel'],
      ['Ahornstrasse 20, Basel', 'Viaduktstrasse , Basel'],
      ['Albert Schweitzer Strasse 10, Basel', 'Kohlenberg 17, Basel'],
      ['alemannengasse 17, Basel', 'Centrahlbahnplatz, Basel'],
      ['Alemannengasse 23, Basel', 'Peter Merian-Weg 8, Basel'],
      ['Allmendstrasse 233, Basel', 'Universitätsspital Basel, Basel '],
      ['Allmendstrasse 4, Basel', 'Petersplatz 1, Basel'],
      ['Allschwilerstrasse 106, Basel', 'Centralbahnstrasse 10 , Basel'],
      ['Allschwilerstrasse 116, Basel', 'Spitalstrasse 8, Architektur Institut, Basel '],
      ['Allschwilerstrasse 116, Basel', 'Steinenvorstadt 55, Kino Pathè Küchlin, Basel'],
      ['Allschwilerstrasse 48, Basel', 'Schneidergasse 28, Basel'],
      ['Altrheinweg 52, Basel', 'Vogesenplatz 1, Basel '],
      ['Am Rheinpark 6, Weil am Rhein', 'J. J. Balmer-Str. 3, Basel'],
      ['Am Weiher 15, Binningen', 'Klingelbergstrasse 82, Basel '],
      ['Amerbachstrasse, , Basel', 'Peter Merian-Weg, Basel'],
      ['Amerikanerstrasse 16, Binningen', 'Petersplatz 1, Basel'],
      ['Amselweg 20, Reinach', 'Baselstrasse 33, Münchenstein'],
      ['An der Auhalde 15, Riehen', 'Zu den Dreilinden 95, Basel'],
      ['arnikastr. 22, Riehen', 'marktplatz, Basel'],
      ['Auf der Lyss 14, Basel', 'Grenzstrasse 15, Basel'] 
    ]; 

    var directionsService = new google.maps.DirectionsService(); 
    var map; 
    var currentRouteIndex = 0;
    // 控制请求间隔,比100ms稍大一点,避免触发限制
    var baseRequestDelay = 110;

    function initialize() { 
      // 修正巴塞尔的正确坐标
      var basel = new google.maps.LatLng(47.5596, 7.5886); 
      var mapOptions = { 
        zoom: 12, 
        center: basel 
      } 
      map = new google.maps.Map(document.getElementById('map'), mapOptions); 
    } 

    function calcRouteWithRetry(start, end, retryCount = 0) { 
      var request = { 
        origin: start, 
        destination: end, 
        travelMode: 'BICYCLING' 
      }; 

      directionsService.route(request, function(result, status) { 
        if (status == 'OK') { 
          var directionsDisplay = new google.maps.DirectionsRenderer({ 
            suppressBicyclingLayer: true, 
            suppressMarkers: true 
          }); 
          directionsDisplay.setMap(map); 
          directionsDisplay.setDirections(result); 
          // 处理下一条路线
          currentRouteIndex++;
          processNextRoute();
        } else if (status === 'OVER_QUERY_LIMIT' && retryCount < 3) { 
          // 遇到限制时,指数退避重试(每次延迟翻倍)
          setTimeout(() => {
            calcRouteWithRetry(start, end, retryCount + 1);
          }, baseRequestDelay * Math.pow(2, retryCount));
        } else { 
          console.error(`Failed to get route for ${start} -> ${end}: ${status}`);
          // 即使失败,也继续处理下一条
          currentRouteIndex++;
          processNextRoute();
        } 
      }); 
    } 

    function processNextRoute() {
      if (currentRouteIndex < addresses.length) {
        setTimeout(() => {
          var nextRoute = addresses[currentRouteIndex];
          calcRouteWithRetry(nextRoute[0], nextRoute[1]);
        }, baseRequestDelay);
      }
    }

    initialize(); 
    // 启动第一条路线的请求
    if (addresses.length > 0) {
      calcRouteWithRetry(addresses[0][0], addresses[0][1]);
    }
  </script> 
</body> 
</html>

关键改进点:

  1. 修正地图中心坐标:把原来的芝加哥坐标改成巴塞尔的正确坐标,确保地图聚焦到目标区域。
  2. 顺序请求+延迟控制:不再同时发送所有请求,处理完一条(无论成功还是失败)后,延迟110ms再发送下一条,严格控制每秒请求数不超过10次。
  3. OVER_QUERY_LIMIT重试逻辑:当遇到请求限制时,最多重试3次,每次延迟时间翻倍(指数退避),这是Google API官方推荐的重试策略。
  4. 正确的setTimeout使用:用箭头函数包裹请求调用,确保延迟后才执行函数,解决了之前立即触发所有请求的问题。

这样修改后,应该就能避免OVER_QUERY_LIMIT异常,顺利加载所有路线了。

内容的提问来源于stack exchange,提问作者samvdst

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:22:12