用$ q串行执行许多任务

时间:2015-08-24 13:33:01

标签: javascript angularjs angular-promise

现在我正在玩$q超级英雄的AngularJS。我有三个asynchronous任务。我们称他们为taskAtaskBtaskC。我想逐个执行它们。目前我正在使用$q的{​​{1}}方法。我正在做以下事情:

all()

这种方法的问题是我的所有任务都是并行执行的。在var taskA = function() { var d = $q.defer(); $timeout(function() { $log.log('Task A'); d.resolve('A is done'); }, Math.random() * 5000); return d.promise; }; var taskB = function() { var d = $q.defer(); $timeout(function() { $log.log('Task B'); // d.resolve('B is done'); d.reject('B is rejected'); }, Math.random() * 5000); return d.promise; }; var taskC = function() { var d = $q.defer(); $timeout(function() { $log.log('Task C'); //d.resolve('C is done'); d.reject('C is rejected'); }, Math.random() * 5000); return d.promise; }; $scope.startWithAll = function() { $log.log('With all started'); var promises = [taskA(), taskB(), taskC()]; $q.all(promises).then( //success callback... function(result) { $log.log(result); }, //error callback function(error) { $log.log(error); }, //progress callback function() { //todo implement it } ).finally(function() { $log.log('I am from finally'); }); }; 的{​​{1}}中,我会在success中获得每项任务的结果。如果任何任务被拒绝,则其余任务将继续执行,但执行错误then并在回调中收到错误array。我想要做的是,首先只应执行callback然后执行object然后taskA如果其中任何一个被拒绝或失败,则不应执行任务的其余部分。并且执行不应该是并行的应该是串行的。要连续执行它们,我这样做:

taskB

所以这解决了我的问题。但问题是,在taskC我得到$scope.startSerial = function() { $log.log('Serially started'); $q.when().then(function(result) { $log.log(result); return taskA(); }).then(function(result) { $log.log(result); return taskB(); }).then(function(result) { $log.log(result); return taskC(); }).finally(function() { $log.log('I am from finally'); }); }; 时,我没有任何问题,所以我们可以省略这一部分。但目前我只有三个任务,所以这种方法很好,但如果明天我有三个以上的任务,那么这将不是一个好的实施方式。有没有其他方法可以这样做因为我不能继续在另一个下面添加多个callback。我创建了plunkr for this。我在想的是创建一个undefined来创建这个任务执行层次结构,但我不知道如何做到这一点。

2 个答案:

答案 0 :(得分:4)

您可以创建一个连接所有承诺的循环:

  function each(arr, func) {
    for (var i = 0; i < arr.length; i++) {
      func(arr[i], i);
    }
  }

  $scope.startSerial = function() {
      var funcs = [taskA, taskB, taskC];
      $log.log('Serially started');
      var s = $q.when();
      each(funcs, function (func) {
          s = s.then(function (result) {
            $log.log(result);
            return func();
          });
      });
      s.finally(function () {
        $log.log('I am from finally');
      });
  }

这应该会导致与原始脚本相同的行为,但您只需调整数组funcs,而不是为每个承诺添加额外的代码块。

答案 1 :(得分:1)

您可以按照希望它们执行的顺序将任务放入数组中,然后循环遍历它们并在任务失败时退出循环。这不是很性感,但它可以完成工作。