Angular $ q多重承诺

时间:2015-12-14 05:43:25

标签: angularjs promise angular-promise

我正在尝试这样做:

  1. 运行fun1
  2. 然后在fun1返回(promise resolves)后,并行运行fun2和fun3(异步)
  3. 然后在fun2,3返回(promises resolve),运行一些fun4并行输入所有并行
  4. 然后在解决所有fun4之后最终运行fun5。

        $q.all({
            fun1: fun1()
        }).then(function(){
    
            return $q.all({
                fun2: fun2(),
                fun3: fun3(),
            });
    
        }).then(function(){
    
            var promises = [];
    
            for(var i = 0; i < 3; i += 1){
                promises.push(fun4(i));
            }
    
            return $q.all(promises);
    
        }).then(function(){
            fun5();
        });
    
  5. 有趣的1~5都是类似于这种模式的api调用:

    var funX = function(){
            return $http({
                method: 'GET',
                url: '/someURL'
            }).success(function(data, status, headers, config) {
                return;
    
            }).error(function(data, status, headers, config) {
                return new Error();
            });
        };
    

    我想确保它们按照我上面描述的顺序运行。看起来像fun4没有等待fun2和fun3返回,而fun5也没有等待所有fun4也返回。

2 个答案:

答案 0 :(得分:0)

因此,我可以使用新的api解决此问题,并删除已弃用的errorsuccess

答案 1 :(得分:-1)

正如我之前所说,可能发生的事情是你的一些Promise失败了。防止$http Promise失败的最佳方法是处理.catch()中的错误(不要使用.success()和{{1} }因为他们已弃用)并返回 truthy 值。

以下是尝试模拟您的流程失败的测试案例(打开控制台并查看记录的内容):

&#13;
&#13;
.error()
&#13;
angular.module('Test', [])
  .controller('Ctrl', function($q, Factory) {
    $q.all({
        fun1: Factory.succeedFunc('1')
      })
      .then(function() {
        return $q.all({
          fun2: Factory.failingFunc('2'),
          fun3: Factory.succeedFunc('3')
        });
      })
      .then(function() {
        var promises = [];
        for (var i = 0; i < 3; i++) {
          promises.push(Math.random() > 0.5 ? Factory.failingFunc('4: ' + i) : Factory.succeedFunc('4: ' + i));
        }
        return $q.all(promises);
      })
      .then(function() {
        Factory.succeedFunc('5');
      });
  })
  .factory('Factory', function($q, $timeout) {
    return {
      failingFunc: function(msg) {
        var deferred = $q.defer();
        console.log('executing', msg);
        $timeout(function() {
          console.log('failed', msg);
          deferred.reject();
        }, 500);
        return deferred.promise;
      },
      succeedFunc: function(msg) {
        var deferred = $q.defer();
        console.log('executing', msg);
        $timeout(function() {
          console.log('succeeded', msg);
          deferred.resolve();
        }, 1000);
        return deferred.promise;
      }
    };
  });
&#13;
&#13;
&#13;

以下是处理拒绝并在<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app="Test" ng-controller="Ctrl"> </div> s&#39;中返回值时发生的情况。 Promise(但要注意不要抛弃.catch(),否则会拒绝新创建的.catch()

&#13;
&#13;
Promise
&#13;
angular.module('Test', [])
  .controller('Ctrl', function($q, IgnoreErrors) {
    var Factory = IgnoreErrors;
    $q.all({
        fun1: Factory.succeedFunc('1')
      })
      .then(function() {
        return $q.all({
          fun2: Factory.failingFunc('2'),
          fun3: Factory.succeedFunc('3')
        });
      })
      .then(function() {
        var promises = [];
        for (var i = 0; i < 3; i++) {
          promises.push(Math.random() > 0.5 ? Factory.failingFunc('4: ' + i) : Factory.succeedFunc('4: ' + i));
        }
        return $q.all(promises);
      })
      .then(function() {
        Factory.succeedFunc('5');
      });
  })
  .factory('Factory', function($q, $timeout) {
    return {
      failingFunc: function(msg) {
        var deferred = $q.defer();
        console.log('executing', msg);
        $timeout(function() {
          console.log('failed', msg);
          deferred.reject();
        }, 500);
        return deferred.promise;
      },
      succeedFunc: function(msg) {
        var deferred = $q.defer();
        console.log('executing', msg);
        $timeout(function() {
          console.log('succeeded', msg);
          deferred.resolve();
        }, 1000);
        return deferred.promise;
      }
    };
  })
  .factory('IgnoreErrors', function(Factory) {
    return {
      failingFunc: function(msg) {
        return Factory.failingFunc(msg).catch(function() {
          return true;
        });
      },
      succeedFunc: function(msg) {
        return Factory.succeedFunc(msg).catch(function() {
          return true;
        });
      }
    }
  });
&#13;
&#13;
&#13;