Angular异步承诺没有正确链接以回拨第一个呼叫以进行第二次呼叫

时间:2017-03-11 02:21:41

标签: javascript angularjs asynchronous promise angular-promise

我想在之前返回一个zipcode 我打电话给第二个服务,这样 - 从我认为我知道的 - 我可以包含一个承诺,然后再请求承诺。所以我想我会把我的第二项服务放在第一项服务的承诺之内。但是用这种方式链接承诺并不友好。

在工厂方法中调用Angular工厂:

var userGeoPromise = userService.getGeoposition().then(function (geoposition) {
    vm.geoposition = geoposition;
            return addressService.reverseGeocode(geoposition.coords);
    }).then(function (data) {
            vm.currentLocation = googleService.googleAddressComponentsToAddress(data.results[0]);
            zipCodeCurrent = vm.currentLocation.zip;
    });

注意上述两件事:

  1. 我将承诺分配给var userGeoPromise
  2. 设置
  3. zipCodeCurrent,其中包含邮政编码
  4. 承诺测试工作正常:

    userGeoPromise.then( function() {
          console.log('should always show', zipCodeCurrent);
    });
    

    第二次服务电话:

    userGeoPromise.then( function() {
         var serviceBase = "http://localhost:2295/api/getservicezip/"+ zipCodeCurrent;
         var serviceZipPromise = $http.get(serviceBase);
         return serviceZipPromise.then(function (results) {
              console.log('serviceZipPromise', results);
              return results.data;
         });
    });
    

    但是当我将serviceZipPromise.then ... 放在另一个承诺中时,网站模式只是旋转

2 个答案:

答案 0 :(得分:0)

切换顺序并添加2个单独的错误处理程序(这是一个很好的做法顺便说一下)

  var serviceZipPromise = $http.get(serviceBase);  // call up 
        return serviceZipPromise.then(function (results) {
            console.log('should always show', zipCodeCurrent);
            userGeoPromise.then(function () {
                //console.log('serviceZipPromise', results);
                console.log('inside servicezip ', zipCodeCurrent);

            }, function (err) {  // error from userGeoPromise
                console.log(err);
            });

             return results.data;  // THIS will return the data
        }, function (err) { // outer error,  this was switched 
            console.log(err);

        });

这不应该是错误,但是对于真正的serviceBase最终使用邮政编码,你可能不得不稍后执行它

为您更新答案

  // created part of the api call
  var xserviceBase = "http://localhost:2295";  // this looks to be your base

  return userGeoPromise.then(function(){
       return $http.get(xserviceBase + '/api/getserviceablezip/' + zipCodeCurrent).then(function(results){
             return results.data;
       })
  });

是的,我知道3回报看起来有点讨厌,但它应该有用

答案 1 :(得分:0)

then回调中,您应返回结果值,而不是将其分配给zipCodeCurrent(或任何其他变量)。您在第一个then回调中正确执行了此操作,但您应该在第二个回调中应用相同的原则:

var userGeoPromise = userService.getGeoposition().then(function (geoposition) {
    vm.geoposition = geoposition;
    return addressService.reverseGeocode(geoposition.coords);
}).then(function (data) {
    vm.currentLocation = googleService.googleAddressComponentsToAddress(data.results[0]);
    return vm.currentLocation.zip; // *** return it
});

注意:我没有触及vm属性的赋值,但通常你应该避免改变那些(显然)存在于这些回调函数范围之外的变量。

Promise测试看起来像这样:

userGeoPromise.then( function(zipCodeCurrent) { // *** add the argument
    console.log('should always show', zipCodeCurrent);
});

2 nd 服务有一个嵌套的then调用,这是要避免的。而不是在嵌套的中间承诺上调用then,而是返回该承诺,并在主承诺链上应用then

userGeoPromise.then( function(zipCodeCurrent) { // *** add the argument as in the test
    var serviceBase = "http://localhost:2295/api/getservicezip/"+ zipCodeCurrent;
    return $http.get(serviceBase); // *** return the promise
}).then( function (results) { // *** move the then-callback to the outer chain
    console.log('serviceZipPromise', results);
    return results.data;
}).catch( function (error) { // *** add error handling at the end of the chain
    console.log('error occurred:', error);
});

请注意嵌套级别永远不会超过1。