我应该如何使用 angular 中的承诺设置异步错误处理?
How should I set up asynchronous error handling with promises in angular?
目前,我的应用程序中的流程看起来像这样
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;
});
}
我发现如果 searchAsync 函数内的承诺失败,则错误处理是该承诺的本地错误处理,外部调用者无法知道它是否失败。如果我需要在 $q.all 'then' 片段中的 searchAsync 调用之后访问 $scope.search.data,我将无法知道它是否由于已处理的捕获或由于没有匹配项。在使用 promises 时,有没有更简洁的方法可以设置我的错误处理?
Is there a cleaner way I can set up my error handling when working with promises?
是:不要在那里处理。
由于 searchAsync
return 是一个承诺,它不应该自己处理错误(除了可选地 转换 它们同时将它们保留为错误)除非它可以有意义地将错误转换为结果(它看起来不像可以)。相反,它应该让其调用者处理错误。您当前拥有的 catch
块将错误(拒绝的承诺)转换为成功(已解决的承诺),值为 undefined
。 (不只是你,这是一个常见的错误。)
要么删除 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;
});
}
...或保留它调用 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;
});
}
一般来说,一个函数应该处理错误或return承诺链,但很少两者都处理。让错误通过链传播到顶层将错误处理留给顶层,同时选择性地让所有层都知道它们发生了。 (再说一次:您可以通过执行某些操作然后重新抛出来转换错误,或者 "tap" 它;这些都很好。静默地将失败转换为 success-with-undefined
不是。:-) )
目前,我的应用程序中的流程看起来像这样
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;
});
}
我发现如果 searchAsync 函数内的承诺失败,则错误处理是该承诺的本地错误处理,外部调用者无法知道它是否失败。如果我需要在 $q.all 'then' 片段中的 searchAsync 调用之后访问 $scope.search.data,我将无法知道它是否由于已处理的捕获或由于没有匹配项。在使用 promises 时,有没有更简洁的方法可以设置我的错误处理?
Is there a cleaner way I can set up my error handling when working with promises?
是:不要在那里处理。
由于 searchAsync
return 是一个承诺,它不应该自己处理错误(除了可选地 转换 它们同时将它们保留为错误)除非它可以有意义地将错误转换为结果(它看起来不像可以)。相反,它应该让其调用者处理错误。您当前拥有的 catch
块将错误(拒绝的承诺)转换为成功(已解决的承诺),值为 undefined
。 (不只是你,这是一个常见的错误。)
要么删除 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;
});
}
...或保留它调用 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;
});
}
一般来说,一个函数应该处理错误或return承诺链,但很少两者都处理。让错误通过链传播到顶层将错误处理留给顶层,同时选择性地让所有层都知道它们发生了。 (再说一次:您可以通过执行某些操作然后重新抛出来转换错误,或者 "tap" 它;这些都很好。静默地将失败转换为 success-with-undefined
不是。:-) )