我的 api 需要时间来处理请求,如何使用 React + SWR 继续检查状态?

my api needs time to process a request, how can I use React + SWR to continue checking on the status?

我的 API 中有一个端点可以在 AWS 上启动一个进程。 这个过程需要时间。它可能会持续几秒或几分钟,具体取决于请求的大小。 目前,我正在重建我的应用程序以使用 swr。但是,在 swr 的新更新之前,我创建了一个递归函数,该函数会在超时时调用自身并不断 ping API 以请求我的 AWS 进程的状态,只有在响应具有适当的响应时才会退出类型。

我想放弃那个递归函数,因为,好吧……它有点老套。不过,我仍然对 swr 很熟悉,而且我不是 NodeJS API 建筑大师,所以我很好奇关于改进以下模式的想法。

理想情况下,最容易实现的目标是以某种方式设置 swr 来处理传入的响应并在响应不是 type: "complete" 时保持 ping 但我不确定如何我会那样做。它几乎只 ping 一次,然后向我显示它当时发现的任何状态。

感谢任何帮助!

tldr;

如何设置 swr 以持续 ping API 直到我的内容加载完成?

我的 API 的一部分,它根据 AWS 流程的进展情况发出响应:

 if (serviceResponse !== undefined) {
        // * task is not complete
        const { jobStatus } = serviceResponse.serviceJob;
        if (serviceJobStatus.toLowerCase() === 'in_progress') {
          return res.status(200).send({ type: 'loading', message: serviceJobStatus });
        }

        if (serviceJobStatus.toLowerCase() === 'queued') {
          return res.status(200).send({ type: 'loading', message: serviceJobStatus });
        }

        if (serviceJobStatus.toLowerCase() === 'failed') {
          return res.status(400).send({ type: 'failed', message: serviceJobStatus });
        }

        // * task is complete
        if (serviceJobStatus.toLowerCase() === 'completed') {
          const { serviceFileUri } = serviceResponse.serviceJob?.Data;
          const { data } = await axios.get(serviceUri as string);
          const formattedData = serviceDataParser(data.results);
          return res.status(200).send({ type: 'complete', message: formattedData });
        }
      } else {
        return res.status(400).send({ type: 'error', message: serviceResponse });
      }
}

我的当前useSWR挂钩:

  const { data: rawServiceData } = useSwr(
    serviceEndpoint,
    url => axios.get(url).then(r => r.data),
    {
      onSuccess: data => {
        if (data.type === 'complete') {
          dispatch(
            setStatus({
              type: 'success',
              data: data.message,
              message: 'service has been successfully generated.',
              display: 'support-both',
            })
          );
          dispatch(setRawService(data.message));
        }
        if (data.type === 'loading') {
          dispatch(
            setStatus({
              type: 'success',
              data: data.message,
              message: 'service job is in progress.',
              display: 'support-both',
            })
          );
        }
      },
    }
  );

经过一番研究,我想我会使用 swr 附带的 refreshInterval 选项。我正在更改组件上布尔值的状态。

  • 虽然请求是 'loading' 状态中的布尔值是 false.
  • 一旦作业为 'complete',状态中的布尔值将设置为 true

我的钩子中有一个三元组,将 refreshInterval 设置为 0(默认值:关闭)或 3000

const [serviceJobComplete, setServiceJobComplete] = useState(false);

  const { data: serviceData } = useSwr(
    serviceEndpoint,
    url => axios.get(url).then(r => r.data),
    {
      revalidateIfStale: false,
      revalidateOnFocus: false,
      revalidateOnReconnect: false,
      refreshInterval: serviceJobComplete ? 0 : 3000,
    ...
    // other options
    }
);

有用的资源: