The problem
Need to cache expensive function calls to avoid recomputation
The solution
function memoize(func, resolver) {
const cache = new Map();
return function(...args) {
const key = resolver ? resolver(...args) : JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
const result = func.apply(this, args);
cache.set(key, result);
return result;
};
}
// Alternative: With cache expiration
function memoizeWithExpiry(func, ttl = 60000) { // 60 seconds default
const cache = new Map();
return function(...args) {
const key = JSON.stringify(args);
const cached = cache.get(key);
if (cached) {
const [value, timestamp] = cached;
if (Date.now() - timestamp < ttl) {
return value;
}
}
const result = func.apply(this, args);
cache.set(key, [result, Date.now()]);
return result;
};
}Parameters
funcfunctionFunction to memoize
resolverfunctionFunction to generate cache key
Put it to work
// Expensive calculation
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
const memoizedFibonacci = memoize(fibonacci);
console.time('First call');
console.log(memoizedFibonacci(40)); // Slow first time
console.timeEnd('First call');
console.time('Second call');
console.log(memoizedFibonacci(40)); // Fast from cache
console.timeEnd('Second call');
// With custom cache key resolver
function getUserData(userId, locale) {
// Simulate API call
return fetch(`/api/users/${userId}?locale=${locale}`);
}
const memoizedGetUser = memoize(getUserData, (userId, locale) => `user-${userId}-${locale}`);