Skip to content

Instantly share code, notes, and snippets.

@kayhadrin
Created July 29, 2016 20:09
Show Gist options
  • Save kayhadrin/bf509ef17d17658692b27107a50a45b8 to your computer and use it in GitHub Desktop.
Save kayhadrin/bf509ef17d17658692b27107a50a45b8 to your computer and use it in GitHub Desktop.
Useful additions to $q
/**
* $q.allSettled returns a promise that is fulfilled with an array of promise state snapshots,
* but only after all the original promises have settled, i.e. become either fulfilled or rejected.
*
* This method is often used in order to execute a number of operations concurrently and be
* notified when they all finish, regardless of success or failure.
*
* @param promises array or object of promises
* @returns {Promise} when resolved will contain an an array or object of resolved or rejected promises.
* A resolved promise have the form { status: "fulfilled", value: value }. A rejected promise will have
* the form { status: "rejected", reason: reason }.
*/
function allSettled(promises) {
var deferred = $q.defer(),
counter = 0,
results = angular.isArray(promises) ? [] : {};
angular.forEach(promises, function (promise, key) {
counter++;
$q.when(promise).then(function (value) {
if (results.hasOwnProperty(key)) {
return;
}
results[key] = {status: 'fulfilled', value: value};
if (!(--counter)) {
deferred.resolve(results);
}
}, function (reason) {
if (results.hasOwnProperty(key)) {
return;
}
results[key] = {status: 'rejected', reason: reason};
if (!(--counter)) {
deferred.resolve(results);
}
});
});
if (counter === 0) {
deferred.resolve(results);
}
return deferred.promise;
}
$q.allSettled = allSettled;
/**
* PromiseQueue class
* @constructor
*/
function PromiseQueue() {
}
/**
* Latest promise
* @type {Promise}
*/
PromiseQueue.prototype.latestPromise = null;
/**
* Runs the given callback function within a Promise.
* Successive calls of #queue(callback) will run each callback in FIFO order.
* @param {Function} callback Callback function that should return a Promise
* @return {Promise} Returns a promise resolved with the result of the callback function
*
* @example
*
* promiseQueue.queue(callback1);
* promiseQueue.queue(callback2);
* promiseQueue.queue(callback3);
*/
PromiseQueue.prototype.queue = function (callback) {
var deferred = $q.defer();
var newPromise = deferred.promise.then(function () {
return $q.when(callback());
});
var latestPromise = this.latestPromise;
if (latestPromise) {
this.latestPromise = latestPromise.finally(function () {
deferred.resolve();
return newPromise;
});
} else {
deferred.resolve();
this.latestPromise = newPromise;
}
return newPromise;
};
/**
* Creates promise queue handler
* @return {Function}
*/
$q.createQueue = function () {
var promiseQueue = new PromiseQueue();
return promiseQueue.queue.bind(promiseQueue);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment