Angular Promises and Chaining:如果链存在业务数据错误,如何打破链

时间:2017-02-21 09:01:42

标签: angularjs promise http-post angular-promise

我以为我这些年来都已经弄清楚以前的项目......显然不是。

目标:获取调用其他服务的服务,如果返回任何类型的错误(不是200 的状态),那么我需要异步的东西等待而不是继续。

在我看来,我似乎并没有真正看到那些伟大的例子,因为它非常简单。

我阅读了关于Angular(1)在幕后做什么的各种文章,我看到有$ q,.then,.success等。

似乎我遇到了return的问题,并且在没有检查问题的情况下进行了其他嵌套和捆绑服务调用。

基本上这张图片显示了回来的内容

数据:null(这很糟糕) errorList数组1 0"此订单无法提交..." (也不好) hasErrors:true(也是坏的)

因此,数据对我来说很重要,可以捕获并显示给用户,然后不再进行更多处理

enter image description here

这是我的操作顺序

this.submitEnrollment = function (enrollment) {
    return getSubmit(requestData);
}

// Which CALLS below

var getSubmit = function (request) {
    return SparkRequestService
        .submitRequest(request)
        .then(
            function (resData) {
                console.log("resData", resData);
                enrollmentService.resetEnrollment();
                return resData;
            }, 
            function (resData) {
                console.log('error');
            }
        );
}

然后我肯定打电话给SparkRequestService.submitRequest(request) 但根据附加的图片,我收到了resData

中的错误

所以,似乎我需要询问resData对吧?那么我真的不应该允许这个其他服务被称为enrollmentService.resetEnrollment();

我如何重构以阻止处理? .then中的if语句?

2 个答案:

答案 0 :(得分:1)

为了防止拒绝处理程序转换被拒绝的承诺履行承诺,请务必在拒绝处理程序中使用throw语句:

var getSubmit = function (request) {
    return SparkRequestService
        .submitRequest(request)
        .then(
            function (resData) {
                console.log("resData", resData);
                enrollmentService.resetEnrollment();
                return resData;
            }, 
            function (errorResponse) {
                console.log('error');
                //IMPORTANT
                //throw to chain rejection
                throw errorResponse;
            }
        );
}

当函数省略returnthrow语句时,该函数返回值undefined。这会将转换已拒绝的承诺转换为以undefined值结算的已履行承诺。

  

问题是......这是一个包含在返回对象中的业务错误

转换对已拒绝承诺的履行承诺,请使用throw声明。

this.submitEnrollment = function (enrollment) {
    var promise = getSubmit(requestData);
    var newPromise = promise.then(function(response) {
         if (response.data.hasErrors) {
             console.log(response.data.errorList);
             response.data.errorList.push("submitEnrollent: Rejected"); 
             //THROW to create rejection
             throw response;
         } else {
             //RETURN response to chain success
             return response;
         }
    });
    return newPromise;
}

当承诺被转换拒绝时,将跳过链中的所有后续成功处理程序。将跟踪链,直到找到拒绝处理程序。

答案 1 :(得分:0)

SparkRequestService.submitRequest(request)中出现错误时,似乎resData返回的承诺未被拒绝。因此,then successCallback 被调用,而不是第二个, errorCallback

因此,在 successCallback 中,您需要检查resData的数据以检查错误并相应地执行操作,例如:

var getSubmit = function (request) {
    return SparkRequestService
        .submitRequest(request)
        .then(function (resData) {
                console.log("resData", resData);
                if(resData === null) { // Check for errors
                    // There is an error, manage it inside this block of code
                    // ...
                    // You can also create a rejected promise with $q.reject() and passing resData containing the errors
                    return $q.reject(resData);
                } else {
                    // Call resetEnrollment() in the ELSE branch so, it is executed only if resData does not contain errors
                    enrollmentService.resetEnrollment();
                    return resData;
                }
            }, 
            function (resData) {
                console.log('error');
            }
        );
};