首页 > 解决方案 > 我的 api 需要时间来处理请求,如何使用 React + SWR 继续检查状态?

问题描述

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

我想转储那个递归函数,因为,嗯......它有点hacky。不过,我仍然很熟悉,swr而且我不是 NodeJS API 构建大师,所以我很好奇在改进下面的模式时会想到什么想法。

理想情况下,最容易实现的目标swr是以某种方式设置来处理传入的响应,如果响应不是,则继续 ping,type: "complete"但我不确定我会如何做到这一点。它几乎只是 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',
            })
          );
        }
      },
    }
  );

标签: node.jsreactjsexpressnext.jsswr

解决方案


经过一番挖掘,我想我会refreshInterval使用swr. 我正在更改组件上的布尔值状态。

  • 当请求正在“加载”时,状态中的布尔值是false.
  • 一旦作业“完成”,状态中的布尔值将设置为true.

我的钩子中有一个三元组,将 设置refreshInterval0(default:off) 或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
    }
);

有用的资源:


推荐阅读