I've been trying to wait for a couple of promises with Angular's $q but there seems to be no option to 'wait for all even when a promis is rejected'. I've created an example (http://jsfiddle.net/Zenuka/pHEf9/21/) and I want a function to be executed when all promises are resolved/rejected, is that possible? Something like:
$q.whenAllComplete(promises, function() {....})
EDIT: In the example you see that the second service fails and immediately after that the function in $q.all().then(..., function(){...})
is being executed. I want to wait for the fifth promise to be completed.
$q is an angular defined service. It's the same as new Promise(). But $q takes things to the next level by enhancing additional feature that developers can use to perform complex tasks more simply. resolve(value) – resolves the derived promise with the value.
$q. defer() allows you to create a promise object which you might want to return to the function that called your login function.
This '$timeout' service of AngularJS is functionally similar to the 'window. setTimeout' object of vanilla JavaScript. This service allows the developer to set some time delay before the execution of the function.
$http is an AngularJS service for reading data from remote servers.
Ok, I've implemeted a basic version myself (I only want to wait for an array of promises). Anyone can extend this or create a cleaner version if they want to :-) Check the jsfiddle to see it in action: http://jsfiddle.net/Zenuka/pHEf9/
angular.module('test').config(['$provide', function ($provide) { $provide.decorator('$q', ['$delegate', function ($delegate) { var $q = $delegate; // Extention for q $q.allSettled = $q.allSettled || function (promises) { var deferred = $q.defer(); if (angular.isArray(promises)) { var states = []; var results = []; var didAPromiseFail = false; if (promises.length === 0) { deferred.resolve(results); return deferred.promise; } // First create an array for all promises with their state angular.forEach(promises, function (promise, key) { states[key] = false; }); // Helper to check if all states are finished var checkStates = function (states, results, deferred, failed) { var allFinished = true; angular.forEach(states, function (state, key) { if (!state) { allFinished = false; } }); if (allFinished) { if (failed) { deferred.reject(results); } else { deferred.resolve(results); } } } // Loop through the promises // a second loop to be sure that checkStates is called when all states are set to false first angular.forEach(promises, function (promise, key) { $q.when(promise).then(function (result) { states[key] = true; results[key] = result; checkStates(states, results, deferred, didAPromiseFail); }, function (reason) { states[key] = true; results[key] = reason; didAPromiseFail = true; checkStates(states, results, deferred, didAPromiseFail); }); }); } else { throw 'allSettled can only handle an array of promises (for now)'; } return deferred.promise; }; return $q; }]); }]);
Analogous to how all()
returns an array/hash of the resolved values, the allSettled()
function from Kris Kowal's Q returns a collection of objects that look either like:
{ state: 'fulfilled', value: <resolved value> }
or:
{ state: 'rejected', reason: <rejection error> }
As this behavior is rather handy, I've ported the function to Angular.js's $q:
angular.module('your-module').config(['$provide', function ($provide) { $provide.decorator('$q', ['$delegate', function ($delegate) { var $q = $delegate; $q.allSettled = $q.allSettled || function allSettled(promises) { // Implementation of allSettled function from Kris Kowal's Q: // https://github.com/kriskowal/q/wiki/API-Reference#promiseallsettled var wrapped = angular.isArray(promises) ? [] : {}; angular.forEach(promises, function(promise, key) { if (!wrapped.hasOwnProperty(key)) { wrapped[key] = wrap(promise); } }); return $q.all(wrapped); function wrap(promise) { return $q.when(promise) .then(function (value) { return { state: 'fulfilled', value: value }; }, function (reason) { return { state: 'rejected', reason: reason }; }); } }; return $q; }]); }]);
Credit goes to:
all
implementation from Angular.js sourceIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With