我正在使用 Google 地图库制作应用程序。我的问题是在创建标记时出现了无法解释的延迟,或者我有一个我看不到的异步问题。
说明: 该代码沿起点和终点之间的路线获取充电站位置,为获取返回的每个站创建 Google 标记(采用 Json 格式)并将它们推送到数组中。稍后,它应该使用这些标记(此处不包括)计算具有中途停留的路线。
问题是它在完成标记创建之前启动计算方法。
为了统一结果,我不会一次获取所有结果。相反,我做了一个循环,执行以下操作:
然后启动路由计算过程(这里替换为alert 'calculateAndDisplayRoute 方法调用)
但实际上循环结束并登录控制台,但未创建最后一个标记,启动警报,只有在此之后您才能看到标记出现在地图上。
您可以尝试以下代码片段:https://codepen.io/reivilo85k/pen/wvowpab
这是有问题的代码(我必须在 codepen 中添加更多代码才能使其工作):
chargingPointsMarkers = [];
markerArray = [];
async callbackHandler(startEndPointsArray, calculateAndDisplayRoute): Promise<void> {
await this.setChargingStationsMarkers();
calculateAndDisplayRoute();
}
function calculateAndDisplayRoute() {
alert('calculateAndDisplayRoute method called')
}
async function setChargingStationsMarkers() {
const polylineMarkersArray = await createMarkersArray();
console.log('Polyline Markers created', polylineMarkersArray);
const baseUrl = 'URL REMOVED';
for (let j = 0; j < polylineMarkersArray.length - 1; j++) {
const origin = polylineMarkersArray[j].getPosition();
const destination = polylineMarkersArray[j + 1].getPosition();
const route = await createRoute(origin, destination);
const encodedPolyline = route.overview_polyline;
const queryUrl = baseUrl + '&polyline='+ encodedPolyline + '&distance=50';
await fetch(queryUrl)
.then((response) => response.json())
.then( async (data) => await createChargerPointMarkers(data))
.then (() => {
const k = j + 1;
const l = polylineMarkersArray.length - 1;
if (j === polylineMarkersArray.length - 2) {
console.log('loop ' + k + ' of ' + l);
console.log('EV markers creation finished');
}else{
console.log('loop ' + k + ' of ' + l);
}
});
}
}
async createChargerPointMarkers(jsonChargingPoints): Promise<void> {
// Convert the Json response elements to Google Markers, places them on the Map and pushes them to an array.
for (const item of jsonChargingPoints) {
const LatLng = new google.maps.LatLng(parseFloat(item.AddressInfo.Latitude), parseFloat(item.AddressInfo.Longitude));
const marker = await new google.maps.Marker({
position: LatLng,
map: this.map,
draggable: false,
});
this.markerArray.push(marker);
this.chargingPointsMarkers.push(marker);
}
}
async createRoute(point1, point2): Promise<google.maps.DirectionsRoute> {
// Returns a Google DirectionsRoute object
const directionsService = new google.maps.DirectionsService();
const request = {
origin: point1,
destination: point2,
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.METRIC
};
return new Promise(resolve => directionsService.route(request,
(result, status) => {
if (status === 'OK') {
resolve(result.routes[0]);
} else {
window.alert('Directions request failed due to ' + status);
}
})
);
}
答案 0 :(得分:1)
正如我在评论中提到的,您的代码按预期工作,问题来自于 alert()
的使用,它在被触发时会阻止您的浏览器执行任何进一步的代码——更重要的是——进一步的用户界面渲染。
这几乎可以使用任何对 DOM 执行某些操作的代码轻松重现。
const el = document.createElement("div");
const text = document.createTextNode("Hello world");
el.appendChild(text);
document.body.appendChild(el);
console.log('done');
alert('done');
警报在节点被添加到 DOM 之后但之前被浏览器渲染(至少在我的浏览器中)被触发。
将代码中的 alert()
替换为 console.log()
并在创建每个 console.log('marker added')
的位置添加另一个 google.maps.Marker()
表明事件的顺序符合您的预期:>
(84) marker added
loop 6 of 6
EV markers creation finished
calculateAndDisplayRoute method called
但是 alert()
在浏览器完成标记渲染之前被触发。
您可能应该避免将 alert()
用于调试目的,或者小心使用它,因为它可能会产生误导。