【问题标题】:How to cache data from async function that uses fetch in Node如何缓存来自 Node 中使用 fetch 的异步函数的数据
【发布时间】:2019-10-22 12:11:17
【问题描述】:

我试图查看是否有办法缓存来自 fetch 异步调用的 json 响应,可能使用 LRU。

我尝试过使用几个包,例如 node-cache 和 lru-cache,但我认为它们不起作用,因为我的函数是异步的。

这就是我的 fetch 函数的基本样子:

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 来获取数据。

【问题讨论】:

标签: javascript arrays json object memcached


【解决方案1】:

这已经有一段时间了,但我同意@sleepy012 的评论。如果我想避免并行调用,技巧应该是缓存承诺,而不仅仅是值。所以这样的事情应该可以工作:

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

【讨论】:

    【解决方案2】:

    异步函数不会阻止缓存结果。您正在查看的库可能无法处理承诺,但这里有一个基本的概念证明,可能有助于开始:

    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)

    只有在之后第一个请求将值返回到缓存后,您才会获得缓存命中

    【讨论】:

    • 实际上,此代码并非 100% 正确:如果在第一个请求仍在等待的情况下对同一 url 进行第二次请求,则将触发第二次获取。根据上下文,这可以是从无害到邪恶的一切。
    猜你喜欢
    • 1970-01-01
    • 2021-09-03
    • 2022-01-21
    • 1970-01-01
    • 2015-02-20
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 2017-12-14
    相关资源
    最近更新 更多