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>
关键改进点:
- 修正地图中心坐标:把原来的芝加哥坐标改成巴塞尔的正确坐标,确保地图聚焦到目标区域。
- 顺序请求+延迟控制:不再同时发送所有请求,处理完一条(无论成功还是失败)后,延迟110ms再发送下一条,严格控制每秒请求数不超过10次。
- OVER_QUERY_LIMIT重试逻辑:当遇到请求限制时,最多重试3次,每次延迟时间翻倍(指数退避),这是Google API官方推荐的重试策略。
- 正确的setTimeout使用:用箭头函数包裹请求调用,确保延迟后才执行函数,解决了之前立即触发所有请求的问题。
这样修改后,应该就能避免OVER_QUERY_LIMIT异常,顺利加载所有路线了。
内容的提问来源于stack exchange,提问作者samvdst
相关产品推荐
相关产品推荐

