我正在使用$ 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()不会执行 成功。
答案 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`