我的$ HTTP调用服务器链。如果一个呼叫失败我想显示通知用户并停止链。起初,我以为我可以使用$ q.reject停止链,但事实证明程序流继续到下一个然后
的错误处理程序。我也曾尝试返回没什么,但流量仍在继续。
我可以停止流动中期链?因此,例如下面的脚本应该打印结果:| A | D | F
而不是结果:| A | D | F | E | H | Ĵ
。
如果流量不能停止中旬链,我必须添加额外的条件在每个然后
的错误处理,还是有更优雅的方式?
\r\r
angular.module(MyModule的,[])。控制器(MyCtrl [$范围,$ q,$超时\r 功能($范围,$ Q $超时){\r $ scope.result =;\r 变种D0 = $ q.defer();\r $超时(函数(){\r d0.reject(A); //承诺将失败\r },1000);\r d0.promise.then(\r 功能(响应){\r $ scope.result + =| +响应+| B;\r 变种D1 = $ q.defer();\r $超时(函数(){\r d1.resolve(C);\r },1000);\r 返回d1.promise;\r },\r 功能(响应){\r $ scope.result + =| +响应+| D;\r 返回$ q.reject(E);\r }\r )。最后(//它应该到此为止了...\r 函数(){$ scope.result + =| F; }\r )。然后(\r 功能(响应){\r $ scope.result + =| +响应+| G;\r },\r 功能(响应){// ...而是继续在这里\r $ scope.result + =| +响应+| H;\r 返回$ q.reject(I);\r }\r )。最后(\r 函数(){$ scope.result + =| J; }\r )\r }\r]);
\r
&LT;脚本SRC =http://ajax.googleapis.com/ajax /libs/angularjs/1.2.22/angular.min.js\"></script>\r&LT; DIV NG-应用=MyModule的NG控制器=MyCtrl&GT;\r 结果:{{结果}}\r&LT; / DIV&GT;
\r\r\r
解决方案这是阅读提供的链接后,我的结论通过@bmceldowney:
流量将始终转到下一然后
,所以为了制止,不提供下一然后
上的路径/承诺,需要停止,并把下一然后
仅在路径/承诺,需要继续。
在我来说,我不希望在链上的第一个承诺收到错误后继续,所以下然后
应在的第二承诺追加的,而不是在第一个然后
:
d0.promise.then( 功能(响应){ // ... 返回d1.promise.then(//追加下一那么在这里... // ... ).catch( // ... )。最后( // ... ); }).catch( // ...)。最后( // ...); // ...而不是在这里
\r\r
angular.module(MyModule的,[])。控制器(MyCtrl [$范围,$ q,$超时\r 功能($范围,$ Q $超时){\r $ scope.result = [];\r\r 变种D0 = $ q.defer();\r $超时(函数(){d0.reject();},1000);\r \r d0.promise.then(\r 功能(响应){\r $ scope.result.push(D0成功);\r\r 变种D1 = $ q.defer();\r $超时(函数(){d1.reject();},1000);\r \r 返回d1.promise.then(\r 功能(响应){$ scope.result.push(D1成功); }\r ).catch(\r 功能(响应){$ scope.result.push(D1失败); }\r )。最后(\r 功能(){$ scope.result.push(finally2); }\r );\r }\r ).catch(\r 功能(响应){$ scope.result.push(D0失败); }\r )。最后(\r 功能(){$ scope.result.push(finally1); }\r );\r }\r]);
\r
&LT;脚本SRC =http://ajax.googleapis.com/ajax /libs/angularjs/1.2.22/angular.min.js\"></script>\r&LT; DIV NG-应用=MyModule的NG控制器=MyCtrl&GT;\r &所述p为H.;结果:或其可/差异无显着\r &LT; DIV NG重复=味精结果&GT; {{味精}}&LT; / DIV&GT;\r&LT; / DIV&GT;
\r\r\r
I have a chain of $http calls to server. If one call fails I want to display notification to user and stop the chain. At first I thought I can use the $q.reject to stop the chain, but it turned out the program flow continues to the next then
's error handler. I have also tried returning nothing, but the flow still continues.
Can I stop the flow mid chain? So for example the script below should print result: |A|D|F
instead of result: |A|D|F|E|H|J
.
If the flow cannot be stopped mid chain, must I add extra condition in each then
's error handler, or is there more elegant way?
angular.module("MyModule", []).controller("MyCtrl", ["$scope", "$q", "$timeout",
function($scope, $q, $timeout) {
$scope.result = "";
var d0 = $q.defer();
$timeout(function() {
d0.reject("A"); // the promise will fail
}, 1000);
d0.promise.then(
function(response) {
$scope.result += "|" + response + "|B";
var d1 = $q.defer();
$timeout(function() {
d1.resolve("C");
}, 1000);
return d1.promise;
},
function(response) {
$scope.result += "|" + response + "|D";
return $q.reject("E");
}
).finally( // it should stop here ...
function() { $scope.result += "|F"; }
).then(
function(response) {
$scope.result += "|" + response + "|G";
},
function(response) { // ... but instead it continues here
$scope.result += "|" + response + "|H";
return $q.reject("I");
}
).finally(
function() { $scope.result += "|J"; }
)
}
]);
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<div ng-app="MyModule" ng-controller="MyCtrl">
result: {{result}}
</div>
解决方案
This is my conclusion after reading the link provided by @bmceldowney:
The flow will always go to the next then
, so in order to stop, don't provide the next then
on the path / promise that needs to stop, and put the next then
only on the path / promise that needs to continue.
In my case I don't want the chain to continue after receiving error on the first promise, so the next then
should be appended on the second promise, not on the first then
:
d0.promise.then(
function(response) {
// ...
return d1.promise.then( // append the next then here ...
// ...
).catch (
// ...
).finally(
// ...
);
}
).catch (
// ...
).finally(
// ...
); // ... instead of here
angular.module("MyModule", []).controller("MyCtrl", ["$scope", "$q", "$timeout",
function($scope, $q, $timeout) {
$scope.result = [];
var d0 = $q.defer();
$timeout(function() { d0.reject(); }, 1000);
d0.promise.then(
function(response) {
$scope.result.push("d0 successful");
var d1 = $q.defer();
$timeout(function() { d1.reject(); }, 1000);
return d1.promise.then(
function(response) { $scope.result.push("d1 successful"); }
).catch (
function(response) { $scope.result.push("d1 failed"); }
).finally(
function() { $scope.result.push("finally2"); }
);
}
).catch (
function(response) { $scope.result.push("d0 failed"); }
).finally(
function() { $scope.result.push("finally1"); }
);
}
]);
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<div ng-app="MyModule" ng-controller="MyCtrl">
<p>result:</p>
<div ng-repeat="msg in result">{{msg}}</div>
</div>