Angular Promises - 从成功跳转到失败回调?
Angular Promises - Jumping from the success to the failure callback?
我觉得我可能正在做一些 Promises 不打算做的事情,但我们开始吧,这就是我想做的:
$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
端点 returns 是 404 或 500...,这将按预期工作,但如果它成功,但有错误数据(例如,isAllGood
是false),那么我希望它能到达失败回调。有没有简单的方法来做到这一点?
我试过调用 $q.defer().reject
并返回那个承诺,但是这只是调用 doOtherStuff
的失败回调。
不要这样做。它的糟糕设计。这是一个更简单的解决方案:
$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();
}
}
是的,有一种简单的方法可以做到。您只需将失败回调 链接到成功回调 之后,而不是紧挨着它 - 请参阅 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();
});
我觉得我可能正在做一些 Promises 不打算做的事情,但我们开始吧,这就是我想做的:
$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
端点 returns 是 404 或 500...,这将按预期工作,但如果它成功,但有错误数据(例如,isAllGood
是false),那么我希望它能到达失败回调。有没有简单的方法来做到这一点?
我试过调用 $q.defer().reject
并返回那个承诺,但是这只是调用 doOtherStuff
的失败回调。
不要这样做。它的糟糕设计。这是一个更简单的解决方案:
$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();
}
}
是的,有一种简单的方法可以做到。您只需将失败回调 链接到成功回调 之后,而不是紧挨着它 - 请参阅 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();
});