现在我在玩超级英雄AngularJS的$q
,我有三个asynchronous
任务,分别叫taskA
,taskB
和taskC
,我想一个一个的执行,现在我用的是$q
的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');
});
};
这种方法的问题是我的所有任务都是并行执行的。在then
的success
中,我在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
中我得到的是undefined
,我对此没有任何问题,所以我们可以省略这一部分。但目前我只有三个任务,所以这种方法是好的,但如果明天我有超过三个任务,那么这将是一个很好的实施方式。有没有其他的方法可以这样做,因为我不能一直在另一个下面添加多个then
。我已经创建了plunkr for this。我正在考虑创建一个service
,它将创建这个任务执行层次结构,但我不知道如何做到这一点。
3条答案
按热度按时间bihw5rsg1#
你可以创建一个循环,连接所有的承诺:
这应该会产生与原始脚本相同的行为,但是您可以简单地调整数组
funcs
,而不是为每个promise添加额外的代码块。lokaqttq2#
你可以把任务按照你希望它们执行的顺序放在一个数组中,然后循环遍历它们,如果一个任务失败了就退出循环。
rt4zxlrg3#
我知道这很老了,但是我最近还是不得不处理这个问题,我最初使用的是一个循环,然后我决定创建一个递归方法,在其中传递promise数组和当前索引promise。