我试图查看是否有一种方法可以使用LRU缓存来自异步获取调用的json响应。
我尝试使用多个软件包,例如节点缓存和lru缓存,但是我认为它们不起作用是因为我的功能是异步的。
这是我的提取函数的基本外观:
const jsonFetch = async (url) => {
try {
const response = await fetch (url)
const json = await response.json();
return json
}
catch (error) {
console.log(error)
}
}
例如,如果我让某人在一分钟内打进我的路线20次,我想轻松地获取数据并在0.03毫秒(而不是0.3毫秒)内返回响应。当前,它始终使用URL来获取数据。
答案 0 :(得分:0)
关于异步功能,没有什么可以防止缓存结果。您正在查看的库很可能无法兑现承诺,但这是一个基本的概念证明,可能有助于使事情开始:
let cache = {}
const jsonFetch = async (url) => {
if (url in cache) { // return cached result if available
console.log("cache hit")
return cache[url]
}
try {
const response = await fetch (url)
const json = response.json();
cache[url] = json // cache response keyed to url
return json
}
catch (error) {
console.log(error)
}
}
jsonFetch("https://jsonplaceholder.typicode.com/todos/1").then((user) => console.log(user.id))
// should be cached -- same url
setTimeout(() => jsonFetch("https://jsonplaceholder.typicode.com/todos/1").then((user) => console.log(user.id)), 2000)
// not in cache
setTimeout(() => jsonFetch("https://jsonplaceholder.typicode.com/todos/2").then((user) => console.log(user.id)), 2000)
只有在第一个请求返回 之后的请求后,您才会获得缓存命中
答案 1 :(得分:0)
这已经有一段时间了,但是我同意@ sleepy012的评论。如果我想避免并行调用,诀窍应该是缓存promise,而不仅仅是值。所以这样的事情应该起作用:
let cache = {}
function cacheAsync(loader) {
return async (url) => {
if (url in cache) { // return cached result if available
console.log("cache hit")
return cache[url]
}
try {
const responsePromise = loader(url)
cache[url] = responsePromise
return responsePromise
}
catch (error) {
console.log('Error', error.message)
}
};
}
function delayedLoader(url) {
console.log('Loading url: ' + url)
return new Promise((r) => setTimeout(r, 1000,'Returning ' + url));
}
const cachedLoader = cacheAsync(delayedLoader);
cachedLoader('url1').then((d) => console.log('First load got: ' + d));
cachedLoader('url1').then((d) => console.log('Second load got: ' + d));
cachedLoader('url2').then((d) => console.log('Third load got: ' + d));
cachedLoader('url2').then((d) => console.log('Fourth load got: ' + d));
console.log('Waiting for load to complete');