使用clearInterval()内部使用效果不起作用。 setInterval()中的功能不断被调用

发布于 2025-02-05 05:01:28 字数 896 浏览 3 评论 0原文

预期的结果: 我正在从API中获得脚本的状态,然后检查状态是什么。 如果status ='xyz',我需要再次调用getStatus函数(使用setInterval), 否则我只需要返回/什么也不做。

问题: 主要问题是ClearInterval()不起作用,即使状态不等于“ XYZ”,也会一次又一次地调用GetStatus()函数(此处10秒)。

请帮忙。提前致谢。

const [intervalId, setIntervalId] = useState();

useEffect(() => {
    getStatus();
  }, []);

  const getStatus = async () => {
    await getScriptStatus()()
      .then(response => {
        if (response.data[0].status == 'XYZ') {
          setIntervalId(
            setInterval(() => {
              getStatus();
            }, 10000)
          );
        }
        else
           return () => clearInterval(intervalId);
      })
      .catch(error => {
        errorMessage(error);
      });

更新: 在使用“如果”条件下使用setInterval()之前,请使用react.useref()代替usestate()进行间隔和清除间隔,或者我使用。 感谢您的有用答案。

Desired Outcome:
I am getting a script's status from an API and then checking what the status is.
If the status = 'XYZ', I need to call the getStatus function again (using setInterval),
else I just need to return/do nothing.

Issue:
The major issue is that clearInterval() is not working and the getStatus() function is getting called after the mentioned interval (10 seconds here) again and again, EVEN THOUGH the status IS NOT EQUAL to 'XYZ'.

Please help out. Thanks in advance.

const [intervalId, setIntervalId] = useState();

useEffect(() => {
    getStatus();
  }, []);

  const getStatus = async () => {
    await getScriptStatus()()
      .then(response => {
        if (response.data[0].status == 'XYZ') {
          setIntervalId(
            setInterval(() => {
              getStatus();
            }, 10000)
          );
        }
        else
           return () => clearInterval(intervalId);
      })
      .catch(error => {
        errorMessage(error);
      });

UPDATE:
Using React.useRef() instead of useState() for intervalId and clearing interval before using setInterval() in the 'if' condition worked or me.
Thank you for the helpful answers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

东风软 2025-02-12 05:01:28

使用settimeout而不是使用setInterval

有关更多详细信息,请访问:

Use setTimeout instead of using setInterval.

For more details visit : Documentation on setTimeout

魄砕の薆 2025-02-12 05:01:28

Intervalid不需要是“状态”,而是存储是参考,而不是状态。

  • 请注意,我将您的功能从使用then()。catch()更改为使用async/等待
  • 我认为您面临的问题是因为React状态是异步的 - setIntervalid没有更新Intervalid,当您尝试已经尝试访问时代码> Intervalid 的新值
const intervalId = useRef(null);

const getStatus = async () => {
    try {
        const response = await getScriptStatus()()
        if (response.data[0].status == 'XYZ') {
            intervalId.current = setInterval(getStatus, 10000);
        }
        else return () => clearInterval(intervalId.current);
    } catch (error) {
        errorMessage(error);
    }
}

另一个建议:

getStatus函数不应充当使用效应功能,因为看到getStatus返回A返回A很困惑函数..然后您需要回到“啊这是一个使用效应功能..返回的功能是一个清理功能..” - 不好..。

所以..我建议的选项:

  • 要么将getState函数更改为GetStatus ..您希望返回一个函数(清理功能)
  • 较少建议:将所有内容直接在useffect中。而且由于您想使用async/等待 - >创建一个self-alling-assync函数:useffect(()=> {(async()=> {等待func();});});},[],[];

update>更新:

除了所有这些 ^
您确实不需要setInterval(就像其他人建议的那样)。 settimeout会很好。但是您可能仍然需要cleartimeout(从clear Interval更改),如果可以在不同的情况下调用函数

intervalId doesn't need to be a "state", rather store is as a ref and not a state.

  • Notice I changed your function from using .then().catch() to using async/await.
  • I think that the problem you're facing is caused because React State is asynchronous - the setIntervalId didn't update the intervalId yet, when you're trying to already access intervalId's new value
const intervalId = useRef(null);

const getStatus = async () => {
    try {
        const response = await getScriptStatus()()
        if (response.data[0].status == 'XYZ') {
            intervalId.current = setInterval(getStatus, 10000);
        }
        else return () => clearInterval(intervalId.current);
    } catch (error) {
        errorMessage(error);
    }
}

Another suggestion:

The getStatus function should not act as a useEffect-function, because it's very confusing to see that getStatus returns a function.. and then you need to trail back to "AH it's a useEffect-function.. and the function returned is a cleanup function.. " - not good.. .

so.. My Suggested Options for that:

  • Either change the getState function to only getStatus.. and then when you call it from inside the useEffect- also handle the case in which you want to return a function (cleanup function)
  • Less suggested: Have all the content straight inside the useEffect. And since you want to use async/await -> create a self-calling-async-function: useEffect(()=>{ (async () => { await func(); })(); }, []);

Update:

In addition to all that ^
You really don't need the setInterval (like others have suggested). setTimeout will do just fine. But you might still want the clearTimeout (changed from clearInterval) if the functio might be called on different occasions

欲拥i 2025-02-12 05:01:28

这里的主要问题很可能是您递归安装新的间隔:函数安装呼叫安装间隔等的函数的间隔,有效地产生间隔的级联。它们或多或少是可撤离的,因为它们的ID在安装它们然后被扔掉的功能范围中占据了临时范围。

您可以在

Main problem here is most probably that you are installing new intervals recursively: function installs interval that calls function that installs interval etc, effectively producing cascade of intervals. These are more or less in-revocable, because their IDs live ephemerally in function scope that installed them and are then thrown away.

You can observe it with slightly modified version of your code in this sandbox.

属性 2025-02-12 05:01:28

更改return()=> clear Interval(Intervalid); to此clear Interval(Intervalid);

Change return () => clearInterval(intervalId); to this clearInterval(intervalId);.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文