如何在链式承诺的中间停止/中断 [英] How to stop/break in the middle of chained promises

查看:23
本文介绍了如何在链式承诺的中间停止/中断的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个对服务器的 $http 调用链.如果一个呼叫失败,我想向用户显示通知并停止链.起初我以为我可以使用 $q.reject 来停止链,但结果程序流继续到下一个 then 的错误处理程序.我也尝试不返回任何内容,但流程仍在继续.

我可以停止流中链吗?例如,下面的脚本应该打印 result: |A|D|F 而不是 result: |A|D|F|E|H|J.

如果流不能在链中停止,我必须在每个then的错误处理程序中添加额外的条件,还是有更优雅的方法?

angular.module("MyModule", []).controller("MyCtrl", ["$scope", "$q","$超时",函数($scope,$q,$timeout){$scope.result = "";var d0 = $q.defer();$超时(功能(){d0.reject("A");//承诺将失败}, 1000);d0.promise.then(功能(响应){$scope.result += "|"+ 响应 + "|B";var d1 = $q.defer();$超时(功能(){d1.resolve("C");}, 1000);返回 d1.promise;},功能(响应){$scope.result += "|"+ 响应 + "|D";返回 $q.reject("E");}).finally(//它应该停在这里...function() { $scope.result += "|F";}).然后(功能(响应){$scope.result += "|"+ 响应 + "|G";},function(response) {//... 但它在这里继续$scope.result += "|"+ 响应 + "|H";返回 $q.reject("I");}).最后(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">结果:{{结果}}

解决方案

这是我阅读提供的链接后的结论来自@bmceldowney:

流程总是会到下一个then,所以为了停止,不要在需要停止的路径/promise上提供下一个then,并将下一个then放在需要继续的路径/promise上.

在我的情况下,我不希望链在第一个承诺上收到错误后继续,所以下一个 then 应该附加到 第二个承诺,而不是在第一个 then 上:

d0.promise.then(功能(响应){//...return d1.promise.then(//在这里添加下一个 then ...//...).抓住 (//...).最后(//...);}).抓住 (//...).最后(//...);//... 而不是这里

angular.module("MyModule", []).controller("MyCtrl", ["$scope", "$q","$超时",函数($scope,$q,$timeout){$scope.result = [];var d0 = $q.defer();$timeout(function() { d0.reject(); }, 1000);d0.promise.then(功能(响应){$scope.result.push("d0 成功");var d1 = $q.defer();$timeout(function() { d1.reject(); }, 1000);返回 d1.promise.then(函数(响应){ $scope.result.push(d1 成功");}).抓住 (函数(响应){ $scope.result.push(d1 失败");}).最后(function() { $scope.result.push("finally2");});}).抓住 (函数(响应){ $scope.result.push(d0 失败");}).最后(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>结果:</p><div ng-repeat="msg in result">{{msg}}</div>

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>

这篇关于如何在链式承诺的中间停止/中断的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆