Last active
April 12, 2022 21:51
-
-
Save fatihsolhan/99811d931139d643f5445fd6ddb49462 to your computer and use it in GitHub Desktop.
Promise based memoization with a given cache size behaving as an LRU cache with an expiry time
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
const LRUCache = (size: number) => { | |
const storage = new Map(); | |
const get = (key: string) => { | |
const value = storage.get(key); | |
if (value) { | |
storage.delete(key); | |
storage.set(key, value); | |
} | |
return value; | |
} | |
const set = (key: string, value: any, timeout: number) => { | |
if (storage.size >= size) { | |
storage.delete(storage.keys().next().value); | |
} | |
storage.set(key, value); | |
setTimeout(() => { | |
storage.delete(key); | |
}, timeout); | |
} | |
const remove = (key: string) => { | |
storage.delete(key); | |
} | |
return { | |
set, | |
remove, | |
get, | |
storage | |
} | |
} | |
const promiseMemoize = ({ fn, size, timeout }: { fn: (...args: any[]) => Promise<any>; timeout: number; size: number }) => { | |
const cache = LRUCache(size); | |
return async (...args: any[]) => { | |
const key = JSON.stringify(args); | |
const value = cache.get(key); | |
if (value) return value; | |
try { | |
const result = await fn(...args); | |
cache.set(key, result, timeout); | |
return result; | |
} catch (e) { | |
return e | |
} | |
} | |
} | |
const fetchToDo = async (id: string) => { | |
console.log(`fetching todo id:${id}`); | |
const res = await fetch(`https://jsonplaceholder.typicode.com/todos/${id}`); | |
return res.json(); | |
} | |
const memoizedFetchToDo = promiseMemoize({ | |
fn: fetchToDo, | |
size: 100, | |
timeout: 1000 | |
}); | |
const run = async () => { | |
const result1 = await memoizedFetchToDo('1'); | |
console.log(result1); | |
// await new Promise((resolve) => setTimeout(resolve, 2000)); // enable this line to see cache expiration working | |
const result2 = await memoizedFetchToDo('1'); | |
console.log(result2); | |
} | |
run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment