基于Google Maps API的JavaScript Promise无法解析问题求助
问题排查与修复:第一个Promise始终Reject的原因
核心错误:同步执行的reject提前终止了Promise
你的两个Promise都存在同一个致命问题:在异步的geocoder.geocode回调函数外部直接调用了reject。Promise的状态是不可逆的,当reject被同步执行后,Promise会立刻进入rejected状态,后续异步回调里的resolve完全无法改变它的状态。
至于你能看到第一个Promise的console.log正常执行,是因为geocoder.geocode是异步操作,它的回调会在所有同步代码(包括reject)执行完毕后才运行,但此时Promise已经是rejected状态了。
额外问题:Promise.all的结果获取方式错误
在Promise.all().then()里,你直接使用checkedDeparture和checkedDestination,这两个是Promise对象本身,不是它们resolve后返回的实际值。必须通过then的参数来获取异步操作的结果。
修复后的代码
修正后的Promise定义
var checkingDeparture = new Promise((resolve, reject) => { console.log('1. checkingDeparture called'); var newDeparture = ''; var geocoder = new google.maps.Geocoder(); geocoder.geocode({'address': $('#startTransfer').val()}, (results, status) => { console.log('2. checkingDeparture geocoder called'); if(status == google.maps.GeocoderStatus.OK) { coordPoint = new google.maps.LatLng(results[0].geometry.location.lat(), results[0].geometry.location.lng()); if(google.maps.geometry.poly.containsLocation(coordPoint, window.venicePolygon)) { console.log('3. checkingDeparture containsLocation called'); newDeparture = 'Piazzale Roma, Venezia, VE, Italia'; } else { newDeparture = $('#startTransfer').val(); } console.log(newDeparture); resolve(newDeparture); } else { // 仅在地理编码失败时调用reject reject('Geocoding failed for departure: ' + status); } }); // 移除外部的同步reject调用 }); var checkingDestination = new Promise((resolve, reject) => { console.log('1. checkingDestination called'); var newDestination = ''; var geocoder = new google.maps.Geocoder(); geocoder.geocode({'address': $('#endTransfer').val()}, (results, status) => { console.log('2. checkingDestination geocoder called'); if(status == google.maps.GeocoderStatus.OK) { coordPoint = new google.maps.LatLng(results[0].geometry.location.lat(), results[0].geometry.location.lng()); if(google.maps.geometry.poly.containsLocation(coordPoint, window.venicePolygon)) { console.log('3. checkingDestination containsLocation called'); newDestination = 'Piazzale Roma, Venezia, VE, Italia'; } else { newDestination = $('#endTransfer').val(); } console.log(newDestination); resolve(newDestination); } else { // 仅在地理编码失败时调用reject reject('Geocoding failed for destination: ' + status); } }); // 移除外部的同步reject调用 });
修正后的调用代码
Promise.all([checkingDeparture, checkingDestination]).then(([departure, destination]) => { console.log(departure + ' ' + destination); var request = { origin: departure, destination: destination, travelMode: google.maps.TravelMode.DRIVING, unitSystem: google.maps.UnitSystem.METRIC }; directionsService.route(request, (result, status) => { console.log('4. checking value of origin: ' + request.origin); console.log('5. checking value of destination:' + request.destination); console.log('6. directionsService called'); if(status == google.maps.DirectionsStatus.OK) { // 执行你的业务逻辑 } else { directionsDisplay.setDirections({routes: []}); theMap.setCenter(window.globalCenter); } }); }).catch(e => { console.log(e); });
关键修复点说明
- 移除同步
reject:将reject移到异步回调内部,仅当地理编码操作失败(status !== OK)时才调用,确保Promise状态由异步操作的结果决定。 - 正确获取异步结果:
then的参数是一个数组,对应Promise.all中每个Promise的resolve结果,通过解构赋值([departure, destination])可以直接拿到实际值。 - 精准错误反馈:在地理编码失败时返回具体的错误状态,便于后续排查问题。
内容的提问来源于stack exchange,提问作者Richard
相关产品推荐
相关产品推荐

