如何使用 Remix.run 定期获取加载器内部?

问题描述 投票:0回答:1

有一个 API,其中包含我的应用程序所需的数据,但我每分钟只能调用它几次。这些数据也在所有用户之间共享(例如,获取当前的比特币价格)。

所以我想在服务器端每分钟调用一次 API,缓存它,然后在有人加载页面时提供结果。简而言之,我想做这样的事情,但我不知道如何构建它:

export const loader = async () => {
  let result;
  if (timeToFetch) {
    result = await getDataFromCache();
  } else {
    result = await getDataFromAPI();
  }
  return json(result);
};

我的问题是如何使用 Remix 构建这个

timeToFetch
功能。我需要某种长时间运行的函数吗?我如何使用 Remix 做到这一点?

我想保持简单,不必使用数据库。最简单/最简单的方法是什么?

一些参考: 如何在 Remix.run 开发模式下使用内存缓存?

javascript reactjs caching remix.run
1个回答
0
投票

这就是 Remix 所说的“不是混音问题”;)

虽然这确实取决于您的部署目标是什么。

主要思想是创建一个类或存储来保持跟踪,然后将其导入到加载器中,或者将其放在 Remix 上下文中。这“就像”你通常在 Nodejs 中所做的那样。

我给你一个节点/快速服务器的例子。

  1. 您可以创建一个名为

    PriceCache.js

    的文件
    // I'm using types to make the intent clearer
    type Price = { bitcoin_to_usd: number }
    
    const FETCH_INTERVAL = 1000 * 60 * 5 // 5 minutes
    
    class PriceCache {
      last_promise: Promise<Price>
      constructor() {
        // I'm just keeping the last fetch promise, so when a fetch just
        // happened, requests might have to wait a bit
        // You can change this to also store the last value directly
        this.last_promise = this.fetchPrice()
    
        // This will "just" run in the background
        setInterval(() => {
          this.last_promise = this.fetchPrice()
        }, FETCH_INTERVAL)
      }
    
      private async fetchPrice() {
        // *Whatever you want to do to fetch the price*
        const response = await fetch('https://api.coindesk.com/v1/bpi/currentprice.json')
        const json = await response.json()
        return json.bpi.USD.rate_float
      }
    }
    
    // Create an instance, so it starts loading when this file is imported
    export let price_cache = new PriceCache()
    

    这只是一个例子,你可以在这里做任何你想做的事情。

  2. 将文件导入到您的 server.entry.js 中

    import "./caches/PriceCache"
    

    您甚至不必从中导入任何内容,但如果您愿意,也可以! 只需通过此导入,缓存现在就会在后台运行。

  3. 在您的加载程序中,导入并使用

    price_cache
    :

    import { price_cache } from "../caches/PriceCache"
    
    export async function loader() {
      // Though still using `await`, most of the time this will be instantaneous
      let prices = await price_cache.last_promise
    
      return { prices }
    }
    

如你所见,混音部分非常小。 您可以在混音应用程序中编写任何节点并使用它。

但我使用的是无服务器后端

那就又要看你的后端了!

例如,使用 cloudflare,您可以使用 KV 存储持久对象 以及 CRON 触发器。这将使事情变得不那么简单,并引入某种数据库;)

Cloudflare 在 Remix 加载器功能中使用寿命较长的资源

在开发模式下使用

在开发过程中每次更改任何内容时,这样的缓存都会重新加载。 这个答案可以帮助您规避这个问题。 请务必小心,因为您对缓存所做的任何更改也不会以这种方式反映出来。您不会是第一个花几个小时才意识到您的缓存已被缓存的人;)

© www.soinside.com 2019 - 2024. All rights reserved.