永远无法解决的javascript Promise问题

Problem with javascript Promise that never resolves

提问人:Richard 提问时间:9/23/2023 更新时间:9/23/2023 访问量:43

问:

我创建了两个自定义承诺,除了它们适用于不同的用户输入之外,它们完全相同。 这两个承诺都使用了 Google Maps API v-3 类和方法。

奇怪的是,每当调用第一个时,它永远不会解析,并且总是返回拒绝状态。 此外,即使它没有解决,promise 代码仍将在我作为控件的几个控制台中执行打印。console.log()

所以这两个是承诺:

var checkingDeparture = new Promise((resolve, reject) => {
    console.log('1. checkingDeparture called');  //first function control
    var newDeparture = '';
    var geocoder = new google.maps.Geocoder();
        
    geocoder.geocode({'address': $('#startTransfer').val()}, (results, status) => {
        console.log('2. checkingDeparture geocoder called');   //second function control
        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');   //third function control
                newDeparture = 'Piazzale Roma, Venezia, VE, Italia';
            }
            else {
                newDeparture = $('#startTransfer').val();
            }
        }
            
        console.log(newDeparture);   //function result control
        resolve(newDeparture);
    });
        
    reject('Sorry there was an error with checkingDeparture promise...');
});
    
var checkingDestination = new Promise((resolve, reject) => {
    console.log('1. checkingDestination called');   //first function control
    var newDestination = '';
    var geocoder = new google.maps.Geocoder();
        
    geocoder.geocode({'address': $('#endTransfer').val()}, (results, status) => {
        console.log('2. checkingDestination geocoder called');   //second function control
        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');   //third function control
                newDestination = 'Piazzale Roma, Venezia, VE, Italia';
            }
            else {
                newDestination = $('#endTransfer').val();
            }
        }
            
        console.log(newDestination);   //function result control
        resolve(newDestination);
    });
        
    reject('Sorry there was an error with checkingDestination promise...');
});

这就是他们被召唤的地方:

var checkedDeparture = checkingDeparture;
var checkedDestination = checkingDestination;
    
Promise.all([checkedDeparture, checkedDestination]).then(() => {
    console.log(checkedDeparture + checkedDestination);   //promise values control
    var request = {
        origin: checkedDeparture,
        destination: checkedDestination,
        travelMode: google.maps.TravelMode.DRIVING,
        unitSystem: google.maps.UnitSystem.METRIC
    };
        
    directionsService.route(request, (result, status) => {
        console.log('4. checking value of origin: ' + request.origin);   //fourth function control
        console.log('5. checking value of destination:' + request.destination);   //fifth function control
        console.log('6. directionsService called');   //sixth function control
        if(status == google.maps.DirectionsStatus.OK) {
            //do things
        }
            
        else {
            directionsDisplay.setDirections({routes: []});
            theMap.setCenter(window.globalCenter);
        }
    });
}).catch(e => {
    console.log(e);
});

我看不出错误实际在哪里,因为似乎可以正确解决。此外,由于从不解析(但仍会执行),因此不会执行所有链接的代码部分。checkingDestinationcheckingDeparture.then()

javascript 异步 google-maps-api-3 承诺

评论


答:

3赞 Slava Knyazev 9/23/2023 #1

你的承诺在解决之前就被拒绝了!

根据定义,承诺只履行一次(无论是承诺还是拒绝),并且只有第一个被接受。因此,如果您编写如下代码:

new Promise((resolve, reject) => {
  setTimeout(() => resolve(), 1000)
  reject() // this runs first
})

它永远不会解决,并且总是拒绝。

而这正是你正在做的事情。

您需要修改您的承诺,使其仅在出现问题时(或超时后)拒绝:

var checkingDeparture = new Promise((resolve, reject) => {
    // snip
        
    geocoder.geocode({'address': $('#startTransfer').val()}, (results, status) => {
        // snip
        if (status === "error") { // Change this for a real check
          reject('Sorry there was an error with checkingDeparture promise...');
        } else {
           resolve(newDeparture);
        }
    });
        
    
});

评论

0赞 Richard 9/23/2023
非常感谢你对我的帮助!我真的错过了这一点。我还注意到,在调用串联函数时,我没有传递承诺值。谢谢!