Skip to content

Instantly share code, notes, and snippets.

@sagiavinash
Last active October 22, 2015 08:14
Show Gist options
  • Save sagiavinash/8240b9e7624370fe372a to your computer and use it in GitHub Desktop.
Save sagiavinash/8240b9e7624370fe372a to your computer and use it in GitHub Desktop.
Memoize functions (aync also)
/**
* memoize(fn[, options]) -> returns a new function which memoizes return values for given args.
* Arguments:
* 1. fn: -> function to be memoized. (pass function's promise if it is async).
* 2. options: {
* isAsync -> (boolean), if function to be memoized is async.
* cacheLimit -> (integer), max no. of results that can be stored in cache.
* }
*/
function memoize(fn, options) {
var memoizeCache = memoize._cache_ || {},
isAsync = options && options.isAsync === true,
cacheLimit = options && options.cacheLimit,
resultFn;
memoizeCache[fn.toString()] = { "queries" : [], "results" : [] };
if (isAsync) {
resultFn = function _memoizedFn() {
var cache = memoizeCache[fn.toString()],
dfd = $.Deferred(),
query = JSON.stringify(arguments),
result;
if (cache.queries.indexOf(query) !== -1) {
result = cache.results[cache.queries.indexOf(query)];
dfd.resolve(result);
} else {
fn.apply(this, arguments).done(function (result){
cache.queries.push(query);
cache.results.push(result);
if (cacheLimit) {
if (cache.queries.length > cacheLimit) {
cache.queries.shift();
cache.responses.shift();
}
}
dfd.resolve(result);
});
}
return dfd.promise();
};
} else {
resultFn = function _memoizedFn() {
var cache = memoizeCache[fn.toString()],
query = JSON.stringify(arguments),
result;
if (cache.queries.indexOf(query) !== -1) {
result = cache.results[cache.queries.indexOf(query)];
return result;
} else {
result = fn.apply(this, arguments);
cache.queries.push(query);
cache.results.push(result);
if (cacheLimit) {
if (cache.queries.length > cacheLimit) {
cache.queries.shift();
cache.responses.shift();
}
}
return result;
}
};
}
return resultFn;
}
/** Examples -
* 1. Sync Function::
* var sum = memoize(function(a, b) {
* return a + b;
* }
*
* Invocation:
* sum(1,2) => 3 -> comes from function execution
* sum(1,2) => 3 -> comes from memoize cache
*
* 2. Async Function::
* var getValue = memoize(function(requestUrlArg) {
* var dfd = $.Deferred(); // can be any promise ex: ES6 Promise or library implementations like RSVP.js or Q.js
* $.ajax({
* url : requestUrlArg,
* }).done(function(response){
* dfd.resolve(response);
* });
* return dfd.promise();
* }, {
* "isAsync" : true,
* "cacheLimit" : "10"
* });
*
* Invocation:
* getValue(requestUrl).done(function(response){
* console.log(response);
* });
* further Invocations with same request url will be cached and instant results until cache size hits 10;
* /
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment