Angular Promises - 从成功跳转到失败回调?

时间:2015-04-28 16:31:04

标签: javascript angularjs angular-promise

我觉得我可能正在做一些承诺没有被设计去做的事情,但是我们走了,这就是我想要做的事情:

$http.get('/api/endpoint/PlanA.json').then(
    function success( response ) {
        if ( response.data.isAllGood ) {
            $scope.myData = response.data;
        }
        else {
            // TODO HERE! Call the failure function!
        }
    },
    function failure() {
        $http.get('/api/endpoint/PlanB.json').then(
            function planBsuccess( response ) {
                $scope.myData = response.data;
            }
        );
    }
).then(function doOtherStuff() {});

这可以按预期工作,例如PlanA端点返回404或500 ...但如果成功,但数据不正确(例如,isAllGood为假),那么我&# 39; d喜欢它来达到失败的回调。有一个简单的方法吗?

我已尝试调用$q.defer().reject并返回该承诺,但这只会调用doOtherStuff的失败回调。

2 个答案:

答案 0 :(得分:1)

是的,有一种简单的方法可以做到这一点。您只需在成功回调之后链接故障回调,而不是在其旁边 - 请参阅When is .then(success, fail) considered an antipattern for promises?以获取更详细的说明。

$http.get('/api/endpoint/PlanA.json').then(function success(response) {
    if (response.data.isAllGood) {
        $scope.myData = response.data;
    } else {
        return $q.reject(); // fail this promise
    }
}).catch(function failure() { // and handle it here (also errors originating from $http)
    return $http.get('/api/endpoint/PlanB.json').then(function planBsuccess(response) {
//  ^^^^^^ don't forget to wait with doOtherStuff for plan B
        $scope.myData = response.data;
    });
}).then(function doOtherStuff() {});

甚至更好,避免$scope任务的代码重复:

$http.get('/api/endpoint/PlanA.json').then(function validate(response) {
    if (response.data.isAllGood)
        return response;
    else
        throw new Error("noGoodData");
}).catch(function failure() {
    return $http.get('/api/endpoint/PlanB.json');
}).then(function success(response) {
    $scope.myData = response.data;
    return doOtherStuff();
});

答案 1 :(得分:0)

不要这样做。它设计糟糕。这是一个更简单的解决方案:

$http.get('/api/endpoint/PlanA.json').then(
    function success( response ) {
        if ( response.data.isAllGood ) {
            $scope.myData = response.data;
        }
        else {
             foo();
        }
    },
    function failure() {
        foo();
    }
).then(function doOtherStuff() {});

foo = function(){
  $http.get('/api/endpoint/PlanB.json').then(
        function planBsuccess( response ) {
            $scope.myData = response.data;
        }
   );
};

话虽如此,我认为即使这样也会滥用$http的设计方式。我会改为做

之类的事情
$http.get('/api/endpoint/PlanA.json').then(
    function success( response ) {
      $scope.myData = response.data;
    },
    function failure() {
        trueFailureFunc();
    }
).then(validateData());

validateData = function(){
    if ( response.data.isAllGood ) {
      $scope.myData = response.data;
    }
     else {
        getDataFromOtherSource();
    }
}