现在我正在玩$q
超级英雄的AngularJS。我有三个asynchronous
任务。我们称他们为taskA
,taskB
和taskC
。我想逐个执行它们。目前我正在使用$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
来创建这个任务执行层次结构,但我不知道如何做到这一点。
答案 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)
您可以按照希望它们执行的顺序将任务放入数组中,然后循环遍历它们并在任务失败时退出循环。这不是很性感,但它可以完成工作。