如何使用$ q完成一个函数的执行,直到另外两个函数完成?

时间:2014-02-14 06:38:50

标签: javascript angularjs

我正在使用$ q的AngularJS实现。

鉴于以下功能:

   doTask1: function ($scope) {
       var defer = $q.defer();
       $http.get('/abc')
           .success(function (data) {
               defer.resolve();
           })
           .error(function () {
               defer.reject();
           });
       return defer.promise;
   },

   doTask2: function ($scope) {
       var defer = $q.defer();
       var x = 99;
       return defer.promise;
   },

我知道我可以延迟执行另一个这样的函数:

os.doTask1()
    .then(function () {
        doTask3();
});

我想同时开始doTask1和doTask2。 有没有办法,我可以做到这一点,仍然延迟执行,以便 在doTask1和doTask2结束之前,doTask3()不会执行 成功。

1 个答案:

答案 0 :(得分:6)

$q.all正是您正在寻找的。 (Documentation

$q.all在数组或对象中接受多个promise,并返回一个全新的promise,当所有传入的promise都被解析时,它将被解析。如果你传递了一个promises数组,那么新的promise将通过一组与promise相对应的值来解决:

$q.all([doTask1(), doTask2()]).then(function(results) {
  // results[0] == result of doTask1
  // results[1] == result of doTask2
  doTask3();
});

如果您传入了一个key-promise对的对象,它将使用一个对象来解析,该对象的键与您传入的对象相匹配,每个值都很好地对应于该键的已解析的promise的值:

$q.all({one: doTask1(), two: doTask2()}).then(function(results) {
  // results.one == result of doTask1
  // results.two == result of doTask1
  doTask3();
});

由于承诺链(例如,当您从then函数返回承诺时,它会创建一个新的承诺,解析为您返回的承诺的已解决值),您可以做一些很酷的事情:< / p>

var bothPromises = $q.all([doTask1(), doTask2()]);

var task3Promise = bothPromises.then(function(results) {
  var result1 = results[0];
  var result2 = results[1];
  return doTask3(result1, result2);
});

task3Promise.then(function(resultOfDoTask3) { ... });

如果传递给$q.all的任何承诺被拒绝,那么返回的承诺也将被拒绝,这一点毫无价值。有关详细信息,请参阅the Angular $q documentation


这几乎与问题无关,但我认为这是一个巧妙的技巧:如果您碰巧使用CoffeeScript,您可以使用解构来获得承诺的已解决值。

对于数组:

$q.all([doTask1(), doTask2()]).then ([result1, result2]) ->
  # ...

对象

$q.all(one: doTask1(), two: doTask2()).then ({one, two}) ->
  # note that you have to use the same key names
  # as in the object you passed to `$q.all`