如何从使用Node中的访存的异步功能缓存数据

时间:2019-06-07 00:32:08

标签: javascript arrays json object memcached

我试图查看是否有一种方法可以使用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来获取数据。

2 个答案:

答案 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');