Created
October 16, 2013 14:46
-
-
Save chrisronline/7008885 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'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