Reputation: 133
I am trying to do this:
Then eventually run fun5 after all fun4 are resolved.
$q.all({
fun1: fun1()
}).then(function(){
return $q.all({
fun2: fun2(),
fun3: fun3(),
});
}).then(function(){
var promises = [];
for(var i = 0; i < 3; i += 1){
promises.push(fun4(i));
}
return $q.all(promises);
}).then(function(){
fun5();
});
fun 1~5 are all api calls similar to this pattern:
var funX = function(){
return $http({
method: 'GET',
url: '/someURL'
}).success(function(data, status, headers, config) {
return;
}).error(function(data, status, headers, config) {
return new Error();
});
};
I want to make sure they are running in the order I describe above. Looks like fun4 did not wait for fun2 and fun3 to return, and fun5 did not wait for all fun4 to return too.
Upvotes: 2
Views: 679
Reputation: 1392
As I said earlier, what's probably happening is that some of your Promise
s are failing. The best way to guard against the $http
Promise
s failing would be to deal with the error in the .catch()
(don't use .success()
and .error()
as they're deprecated) and return a truthy value.
Following is a test case trying to simulate your process failing (open up the console and see what gets logged):
angular.module('Test', [])
.controller('Ctrl', function($q, Factory) {
$q.all({
fun1: Factory.succeedFunc('1')
})
.then(function() {
return $q.all({
fun2: Factory.failingFunc('2'),
fun3: Factory.succeedFunc('3')
});
})
.then(function() {
var promises = [];
for (var i = 0; i < 3; i++) {
promises.push(Math.random() > 0.5 ? Factory.failingFunc('4: ' + i) : Factory.succeedFunc('4: ' + i));
}
return $q.all(promises);
})
.then(function() {
Factory.succeedFunc('5');
});
})
.factory('Factory', function($q, $timeout) {
return {
failingFunc: function(msg) {
var deferred = $q.defer();
console.log('executing', msg);
$timeout(function() {
console.log('failed', msg);
deferred.reject();
}, 500);
return deferred.promise;
},
succeedFunc: function(msg) {
var deferred = $q.defer();
console.log('executing', msg);
$timeout(function() {
console.log('succeeded', msg);
deferred.resolve();
}, 1000);
return deferred.promise;
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="Test" ng-controller="Ctrl">
</div>
And here is what happens when you deal with the rejection and return a value in the Promise
s' .catch()
(though be careful not to throw in the .catch()
as that will reject the newly created Promise
too:
angular.module('Test', [])
.controller('Ctrl', function($q, IgnoreErrors) {
var Factory = IgnoreErrors;
$q.all({
fun1: Factory.succeedFunc('1')
})
.then(function() {
return $q.all({
fun2: Factory.failingFunc('2'),
fun3: Factory.succeedFunc('3')
});
})
.then(function() {
var promises = [];
for (var i = 0; i < 3; i++) {
promises.push(Math.random() > 0.5 ? Factory.failingFunc('4: ' + i) : Factory.succeedFunc('4: ' + i));
}
return $q.all(promises);
})
.then(function() {
Factory.succeedFunc('5');
});
})
.factory('Factory', function($q, $timeout) {
return {
failingFunc: function(msg) {
var deferred = $q.defer();
console.log('executing', msg);
$timeout(function() {
console.log('failed', msg);
deferred.reject();
}, 500);
return deferred.promise;
},
succeedFunc: function(msg) {
var deferred = $q.defer();
console.log('executing', msg);
$timeout(function() {
console.log('succeeded', msg);
deferred.resolve();
}, 1000);
return deferred.promise;
}
};
})
.factory('IgnoreErrors', function(Factory) {
return {
failingFunc: function(msg) {
return Factory.failingFunc(msg).catch(function() {
return true;
});
},
succeedFunc: function(msg) {
return Factory.succeedFunc(msg).catch(function() {
return true;
});
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="Test" ng-controller="Ctrl">
</div>
Upvotes: -1
Reputation: 133
So I was able to resolve this issue by using the new api and get rid of deprecated error
and success
.
Upvotes: 0