Last active
October 22, 2015 08:14
-
-
Save sagiavinash/8240b9e7624370fe372a to your computer and use it in GitHub Desktop.
Memoize functions (aync also)
This file contains hidden or 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
/** | |
* 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