Skip to content

Instantly share code, notes, and snippets.

@chrisronline
Created October 16, 2013 14:46
Show Gist options
  • Save chrisronline/7008885 to your computer and use it in GitHub Desktop.
Save chrisronline/7008885 to your computer and use it in GitHub Desktop.
'use strict';
angular.module('gigwellApp')
/**
* Wraps a promise call to provide a "singleton" for that promise so attempts to recreate that promise will simply
* reuse the singleton one.
*
* Supports manually purging and also purging based on a configurable TTL (in ms)
*/
.factory('singletonPromise', function($q) {
var dataCache = {},
errorCache = {},
promiseCache = {},
ttlCache = {},
DEFAULT_TTL_IN_MS = 5000;
return {
purge: function(key) {
dataCache = _.omit(dataCache, key);
errorCache = _.omit(errorCache, key);
ttlCache = _.omit(ttlCache, key);
},
purgeAll: function() {
dataCache = {};
errorCache = {};
ttlCache = {};
},
// Manually get the data - not sure if this makes sense here, but pretty sure it's a small perf gain for filters using this service since
// filters are called a ton
get: function(key) {
return _.has(dataCache, key) ? dataCache[key] : null;
},
create: function(key, promiseGetter, ttl) {
var deferred = $q.defer();
if (_.has(ttlCache, key)) {
// Purges the cache if enough time has passed
if (ttlCache[key] + (ttl || DEFAULT_TTL_IN_MS) < new Date().getTime()) {
this.purge(key);
}
}
if (_.has(dataCache, key)) {
deferred.resolve(dataCache[key]);
}
else if (_.has(errorCache, key)) {
deferred.reject(errorCache[key]);
}
else if (_.has(promiseCache, key)) {
promiseCache[key].push(deferred);
}
else {
promiseCache[key] = [ deferred ];
ttlCache[key] = new Date().getTime();
promiseGetter().then(
function(success) {
dataCache[key] = success.data.data;
_.each(promiseCache[key], function(promise) { promise.resolve(dataCache[key]); });
promiseCache = _.omit(promiseCache, key);
},
function (error) {
errorCache[key] = error;
_.each(promiseCache[key], function(promise) { promise.reject(errorCache[key]); });
promiseCache = _.omit(promiseCache, key);
}
);
}
return deferred.promise;
}
};
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment