我正在使用 Google 地图库制作一个应用程序,并带有一个调用两组进程的回调函数。
我想确保在启动第二个进程之前完成第一个进程。
这意味着我希望 callbackHandler 方法在调用 calculateAndDisplayRoute() 之前等待在方法 createChargerPointMarkers() 中创建的所有标记在地图上创建、推送和设置,但事实并非如此。
相反,它会耐心等待直到最后一个循环,但在最后一个循环真正完成之前启动了 calculateAndDisplay 方法
假设你有 3 个循环,会发生什么: “循环 1 出 3” (您可以看到在地图上设置的标记) “循环 2 出 3” (您可以看到在地图上设置的标记) “循环 3 出 3” “EV标记创作完成” “路线计算开始” 只有在此之后,您才会看到最后一个循环的标记被创建并设置在地图上。
我想我错误地组织了承诺/等待。如何强制编译器在继续之前等待所有标记创建和设置?
备注:很难/不可能展示一个可重现的功能示例,因为折线创建方法使用外部库(epolys.js,非常有用),没有它,CodePen 和 JSFiddle 无法理解代码。您还需要更多的代码来创建 Google 地图、标记等。所以这里放的代码太多了
如果您愿意查看整个代码,我可以共享该存储库,但它很长(到目前为止有 441 行)并且只有我在此处放置的方法与此问题相关。
chargingPointsMarkers = [];
markerArray = [];
async callbackHandler(startEndPointsArray, calculateAndDisplayRoute): Promise<void> {
await this.setChargingStationsMarkers();
calculateAndDisplayRoute();
}
calculateAndDisplayRoute(): Promise<void> {
console.log('calculation started')
}
async setChargingStationsMarkers(): Promise<void> {
const polyline = await this.createPolyline();
const polylineMarkersArray = await this.createMarkersOnPolyline(polyline);
// This makes a Google Polyline object.I voluntarily did not include the polyline methods,
// they are not relevant and are resolved before the following loop starts
const baseUrl = 'https://api.openchargemap.io/v3/poi/output=json&maxresults=100&verbose=false&includecomments=true';
for (let j = 0; j < polylineMarkersArray.length - 1; j++) {
const origin = polylineMarkersArray[j].getPosition();
const destination = polylineMarkersArray[j + 1].getPosition();
const route = await this.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 this.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);
}
})
);
}