简体   繁体   English

我应该如何使用angular中的promise设置异步错误处理?

[英]How should I set up asynchronous error handling with promises in angular?

Currently, the flow in my application looks something like this 目前,我的应用程序中的流程看起来像这样

function searchAsync() {
    $scope.search.inProgress = true;

    return Service.search($scope.search.parameters).$promise
        .then(function (data) {
            $scope.search.data = data;
        }).catch(function (e) {
            displayError(e);
        }).finally(function () {
            $scope.search.inProgress = false;
        });
}

function initialize() {
    var promises = [];

    promises.push(setLookupsAsync($scope.categories, LookupResource.getCategories));
    promises.push(setLookupsAsync($scope.topics, LookupResource.getTopics));
    promises.push(setLookupsAsync($scope.races, LookupResource.getRaces));
    promises.push(setLookupsAsync($scope.genders, LookupResource.getGenders));

    $q.all(promises).then(function () {
        searchAsync()
    }).catch(function (e) {
        displayError(e);
    }).finally(function () {
        $scope.page.loaded = true;
    });
}

I've found that if the promise inside the searchAsync function fails, the error handling is local to that promise and the outside caller has no way of knowing if it failed or not. 我发现,如果searchAsync函数中的promise失败,则错误处理仅限于该promise,外部调用者无法知道它是否失败。 If I needed to access the $scope.search.data after the searchAsync call in the $q.all 'then' piece, I would have no way of knowing if it had no items due to a handled catch or due to no matching items. 如果我需要在$ q.all'then'件中的searchAsync调用之后访问$ scope.search.data,我将无法知道它是否由于处理过的捕获或由于没有匹配项而没有任何项。 Is there a cleaner way I can set up my error handling when working with promises? 使用诺言时,是否可以使用一种更干净的方式来设置错误处理?

Is there a cleaner way I can set up my error handling when working with promises? 使用诺言时,是否可以使用一种更干净的方式来设置错误处理?

Yes: Don't handle it there. 是的:不要在那里处理。

Since searchAsync returns a promise, it shouldn't handle errors itself (other than optionally transforming them while keeping them as errors) unless it can meaningfully convert an error into a result (which it doesn't look like it can). 由于searchAsync返回一个searchAsync ,因此除非它可以有意义地将错误转换为结果(看起来不可能),否则它不应该自己处理错误(除了可以选择其保留为错误的方式进行转换)。 Instead, it should let its caller handle errors. 相反,它应该让其调用方处理错误。 The catch block you currently have transforms an error (a rejected promise) into a success (a resolved promise) with the value undefined . 您当前拥有的catch块将值undefined的错误(拒绝的promise)转换为成功(解决的promise)。 (It's not just you, this is a common mistake.) (不仅仅是您,这是一个常见错误。)

Either remove the catch : 要么删除catch

function searchAsync() {
    $scope.search.inProgress = true;

    return Service.search($scope.search.parameters).$promise
        .then(function (data) {
            $scope.search.data = data;
        }).finally(function () {
            $scope.search.inProgress = false;
        });
}

...or keep it to call displayError but rethrow the error: ...或保留它以调用displayError但重新抛出错误:

function searchAsync() {
    $scope.search.inProgress = true;

    return Service.search($scope.search.parameters).$promise
        .then(function (data) {
            $scope.search.data = data;
        }).catch(function (e) {
            displayError(e);
            throw e; // <=========
        }).finally(function () {
            $scope.search.inProgress = false;
        });
}

In general, a function should either handle errors or return the promise chain, but rarely both. 一般情况下,一个函数应该要么处理错误返回的承诺链,但很少两者。 Letting errors propagate through the chain to the top level leaves error handling to the top level, while optionally letting all levels know they occurred. 让错误通过链传播到顶层,将错误处理留给顶层,同时有选择地让所有级别知道它们发生了。 (Again: You can transform an error, or "tap" it by doing something and then re-throwing; those are fine. Silently converting failure to success-with- undefined is not. :-) ) (再次:您可以转换错误,或通过执行某些操作然后重新抛出来“敲击”错误;这些都很好。将失败无声地转换为成功- undefined是不可行的::))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM