简体   繁体   English

正在等待 API 使用 React Hooks (useEffect) 更新状态?

[英]Awaiting status update from API with React Hooks (useEffect)?

I am trying to achieve the following:我正在努力实现以下目标:

Using React + React Hooks + useEffect使用 React + React Hooks + useEffect

  1. Make an API post request发出 API 发帖请求
  2. Receiving an ID领取身份证
  3. Making another post request using the ID to get the status (Queued or Completed)使用 ID 发出另一个发布请求以获取状态(排队或已完成)

So basically所以基本上

{
  id: "xxxxxxx",
  status: "queued"
}

Is what I get back.是我回来的。 Now the processing time varies, but I want to periodically check if the status has changed from "queued" to "completed".现在处理时间有所不同,但我想定期检查状态是否从“排队”变为“已完成”。 And while it's not completed, I want to display a loading spinner.虽然还没有完成,但我想显示一个加载微调器。

What would be the best way to do this?最好的方法是什么? Would this be possible with promises / async functions?这可以用 promises / async 函数实现吗? Or do I have to use some kind of interval to re-check the status periodically?或者我是否必须使用某种间隔来定期重新检查状态?

I am basically trying to use this in React: https://docs.assemblyai.com/walkthroughs#authentication我基本上是想在 React 中使用它: https://docs.assemblyai.com/walkthroughs#authentication

You could do something like this:你可以这样做:

// Mocks - after the 2nd attempt getStatus will return "done"
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
let attempt = 0;
const getId = async () => {
  console.log("getId");
  await delay();
  return { id: "id1" };
};
const getStatus = async (id) => {
  console.log("getStatus", { id, attempt });
  attempt += 1;
  await delay(1000);
  return {
    id,
    status: attempt < 2 ? "queued" : "done"
  };
};

export default function App() {
  const [id, setId] = useState();
  const [isDone, setIsDone] = useState(false);

  useEffect(() => {
    const effect = async () => {
      const { id } = await getId();
      setId(id);
    };

    effect();
  }, []);

  useEffect(() => {
    let cancelled = false;
    const effect = async () => {
      let { status } = await getStatus(id);
      while (status !== "done") {
        if (cancelled) {
          return;
        }
        await delay(1000);
        status = (await getStatus(id)).status;
      }

      setIsDone(true);
    };

    if (id) {
      effect();
    }
    return () => {
      cancelled = true;
    };
  }, [id]);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>{isDone ? "Done" : "Loading..."}</h2>
    </div>
  );
}

Note: this is simplified and does not cover error scenarios, but shows how this can be put together注意:这是简化的,不包括错误场景,但展示了如何将它们放在一起

编辑可疑-tesla-2ue0m0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM