What happens with $q.all() when some calls work and others fail?
Solution 1:
I believe since the promise library is based on Q
implementation, as soon as the first promise gets rejected, the reject callback is called with the error. It does not wait for other promises to resolved. See documentation of Q
https://github.com/kriskowal/q. For Q.all this is what is mentioned
The all function returns a promise for an array of values. When this promise is fulfilled, the array contains the fulfillment values of the original promises, in the same order as those promises. If one of the given promises is rejected, the returned promise is immediately rejected, not waiting for the rest of the batch.
Solution 2:
It's been a while since this question was posted, but maybe my answer might still help someone. I solved a similar problem on my end by simply resolving all promises, but with a return I could process later and see if there were any errors. Here's my example used to preload some image assets:
var loadImg = function(imageSrc) {
var deferred = $q.defer();
var img = new Image();
img.onload = function() {
deferred.resolve({
success: true,
imgUrl: imageSrc
});
};
img.onerror = img.onabort = function() {
deferred.resolve({
success: false,
imgUrl: imageSrc
});
};
img.src = imageSrc;
return deferred.promise;
}
Later I can see which ones are errorious:
var promiseList = [];
for (var i = 0; i < myImageList.length; i++) {
promiseList[i] = loadImg(myImageList[i]);
}
$q.all(promiseList).then(
function(results) {
for (var i = 0; i < results.length; i++) {
if (!results[i].success) {
// these are errors
}
}
}
);
Solution 3:
Edit: Only supported in Kris Kowal's Q - but still a useful tidbit
If you want to process all of them without rejecting right away on failure use allSettled
Here's what the docs say:
If you want to wait for all of the promises to either be fulfilled or rejected, you can use allSettled.
Q.allSettled(promises)
.then(function (results) {
results.forEach(function (result) {
if (result.state === "fulfilled") {
var value = result.value;
} else {
var reason = result.reason;
}
});
});