【发布时间】:2021-05-07 20:53:24
【问题描述】:
我正在使用 Google 地图库制作应用程序。我的问题是创建标记时出现无法解释的延迟,或者我有一个我看不到的异步问题。
说明: 该代码沿起点和终点之间的路线获取充电站位置,为获取返回的每个站创建 Google 标记(以 Json 格式)并将它们推送到数组中。稍后它应该使用这些标记(不包括在此处)来计算中途停留的路线。
问题是它在完成创建标记之前启动计算方法。
为了协调结果,我不会一次获取所有结果。相反,我做了一个循环,执行以下操作:
- 创建路线并从中提取编码折线(用于 URL)
- 获取结果
- 创建标记,在地图上设置它们并将它们推送到数组上
- 登录控制台作业完成('EV 标记创建完成')
然后它启动路由计算过程(这里替换为调用的alert 'calculateAndDisplayRoute 方法)
但实际上循环结束并登录控制台,但未创建最后一个标记,警报已启动,只有在您看到标记出现在地图上之后。
你可以试试下面的代码 sn -p :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);
}
})
);
}
【问题讨论】:
-
我认为您的代码没有问题。我相信问题在于使用
alert()会阻止 UI 渲染,直到您单击确定。如果我在创建每个标记后添加一个console.log('marker added')并用另一个控制台日志替换警报并执行您的代码,在最后一个循环中,我得到以下序列: (84) marker added > loop 6 of 6 > EV 标记创建完成 > 调用 calculateAndDisplayRoute 方法,因此您可以看到在调用calculateAndDisplayRoute之前创建了 84 个标记。只有alert()在您的浏览器完成渲染之前触发。 -
@MrUpsidown 感谢您的评论并花时间在我的代码上。这非常有用。
-
既然答案已经得到解答,我将删除 CodePen 中的 fetch URL
标签: javascript typescript asynchronous promise alert