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

无途经点多路线异步请求致顺序错乱及结果数组为空问题

解决Google Maps API异步路线请求的顺序错乱与结果数组为空问题

我明白你遇到的麻烦了——因为Google Maps Directions API是异步请求,循环里同时发起多个调用时,响应返回的顺序完全不确定,导致路线结果乱序,而且同步代码里打印数组的时候,异步请求还没完成,所以数组是空的。加上不能用途经点方案,得按段处理A->B、B->C、C->D的路线,我们可以用Promise结合async/await来解决这个问题,确保请求按顺序执行,结果也能正确按顺序存入数组。

问题根源分析

  1. 异步请求无序性:你原来的循环里同步触发多个requestDirections,每个里面的directionsService.route是异步的,哪个请求先返回就先执行renderDirections,完全不按请求顺序来,所以routeArrayResult里的元素顺序会乱。
  2. 同步代码提前执行:循环里的console.log是同步运行的,这时候所有异步请求还在等待响应,所以routeArrayResult肯定是空的。
  3. doClickClear的隐藏问题:原来的directionsRenderer是renderDirections里的局部变量,外部的doClickClear根本访问不到,所以点击清除按钮不会生效。

完整解决方案代码

我们先把API调用封装成Promise,再用async/await按顺序发起请求,同时修复清除功能:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <style type="text/css">
        html { height: 100% }
        body { height: 100%; margin: 0px; padding: 0px }
    </style>
    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3"></script>
    <script type="text/javascript">
        var map;
        var routeColor;
        var myOptions = {
            zoom:7,
            mapTypeId: google.maps.MapTypeId.ROADMAP,
        };
        var routeArray = ['61.84448683734486, 8.85223388671875', '61.75298123367897, 9.078826904296875', '61.484039,7.645798', '61.944118091023746,7.97882080078125'];
        var routeArrayResult = [];
        var routeColorArray = ['#ff00ff', '#40ff00', '#0040ff', '#ffbf00', '#00ffff', '#ff00ff', '#ff8000'];
        const directionsRenderers = []; // 存储所有路线渲染实例,用于清除

        function initMap() {
            map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
        }

        function renderDirections(result, order) {
            const directionsRenderer = new google.maps.DirectionsRenderer({
                suppressMarkers: true,
                suppressInfoWindows: true // 修复原代码的拼写错误:suppresInfoWindows
            });
            directionsRenderer.setOptions({
                polylineOptions: {
                    strokeWeight: 3,
                    strokeOpacity: 0.5,
                    strokeColor: routeColorArray[order] // 绑定对应顺序的颜色
                }
            });
            directionsRenderer.setMap(map);
            directionsRenderer.setDirections(result);
            directionsRenderers.push(directionsRenderer); // 保存实例到数组

            const route = result.routes[0];
            const summaryPanel = document.getElementById("directions_panel");
            const routeInfo = `Route ${order + 1} distance:${route.legs[0].distance.text}`;
            routeArrayResult.push(routeInfo);
            summaryPanel.innerHTML += `${routeInfo}<br>`;
            console.log(`Render - Push result to Array id:${order + 1}`);
        }

        // 把Directions API调用封装成Promise
        function getDirections(start, end) {
            return new Promise((resolve, reject) => {
                const directionsService = new google.maps.DirectionsService();
                const request = {
                    origin: start,
                    destination: end,
                    travelMode: google.maps.DirectionsTravelMode.DRIVING,
                    drivingOptions: {
                        departureTime: new Date("08/08/2018")
                    }
                };
                directionsService.route(request, (result, status) => {
                    if (status === google.maps.DirectionsStatus.OK) {
                        resolve(result);
                    } else {
                        reject(new Error(`Directions request failed: ${status}`));
                    }
                });
            });
        }

        // 用async/await按顺序发起请求
        async function doClick3() {
            routeArrayResult = [];
            const summaryPanel = document.getElementById("directions_panel");
            summaryPanel.innerHTML = "";
            // 先清除之前的路线
            directionsRenderers.forEach(r => r.setMap(null));
            directionsRenderers.length = 0;

            for (let i = 0; i < routeArray.length - 1; i++) {
                routeColor = routeColorArray[i];
                console.log(`doclick3 [${i}] From:${routeArray[i]} To:${routeArray[i+1]} in color ${routeColor}`);
                
                try {
                    // 等待当前请求完成后再发起下一个
                    const result = await getDirections(routeArray[i], routeArray[i+1]);
                    renderDirections(result, i);
                } catch (error) {
                    alert(error.message);
                }
            }

            // 所有请求完成后再打印结果,此时数组已填充完整
            console.log("Total resultslength: " + routeArrayResult.length + " total routes:" + (routeArray.length - 1));
            console.log("routeArrayResult: ", routeArrayResult);
        }

        function doClickClear() {
            directionsRenderers.forEach(renderer => {
                renderer.setMap(null);
            });
            directionsRenderers.length = 0;
            routeArrayResult = [];
            document.getElementById("directions_panel").innerHTML = "";
        }
    </script>
</head>
<body onload="initMap()">
    <div id="map_canvas" style="float:left;width:70%;height:100%;"></div>
    <div id="control_panel" style="float:right;width:30%;text-align:left;padding-top:20px">
        <input type="button" name="resetButton" onclick="doClick3();" value="calc 3 routes">
        <input type="button" name="resetButton" onclick="doClickClear();" value="clear routes">
        <div id="directions_panel" style="margin:20px;background-color:#FFEE77;"></div>
    </div>
</body>
</html>

关键改进点说明

  1. Promise封装API调用:把directionsService.route包装成返回Promise的函数getDirections,这样就能用async/await来控制异步流程。
  2. async/await顺序执行:doClick3改成async函数,循环里用await等待每个请求完成后再处理下一个,确保路线请求和结果存入数组的顺序完全和A->B、B->C、C->D一致。
  3. 修复清除功能:用数组directionsRenderers存储所有创建的DirectionsRenderer实例,清除时遍历数组把每个实例从地图上移除,同时清空数组和结果数组。
  4. 修复拼写错误:原代码里的suppresInfoWindows改成正确的suppressInfoWindows,避免功能异常。
  5. 延迟结果打印:把数组长度的打印放在循环结束后,确保所有异步请求都完成,此时routeArrayResult已经填充了所有路线信息。

这样修改后,你就能得到顺序完全正确的路线结果数组,而且不会再出现数组为空的问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:31:40