javascript - 如何最好地利用 setInterval 来轮询 API 端点?

标签 javascript reactjs axios

所以我有这个端点,我想多次调用它,直到得到所需的响应,并且我想知道这种方法是否是处理它的有效方法。

所以这个端点,我们称之为 /ping 返回一个具有如下值的对象 {ping: 1} 现在我想点击这个端点几次更多次数或直到 ping 值从 1 更改为 2。这是我目前的方法,但有些东西不适合我,我想要第二双眼睛。

import React from "react";
import axios from "axios";

function App() {
  const apiCall = async () => {
    try {
      const ping = await axios({
        url: "https://rest.ensembl.org/info/ping?content-type=application/json",
        method: "GET",
        headers: {
          accept: "Application/json",
          "Content-Type": "Application/json",
        },
      });
      return ping.data;
    } catch (error) {
      return error.response;
    }
  };

  const myIntervalFunc = () => {
    let myCall = async () => await apiCall();
    let retryNum = 0;
    myCall();
    let interval = setInterval(async () => {
      let intervalCall = await myCall();
      if (intervalCall.ping !== 2) {
        retryNum++;
        console.log("INTERVAL DATA ", intervalCall);
      }
      if (retryNum === 6) {
        clearInterval(interval);
      }
    }, 3000);
  };

  return <button onClick={() => myIntervalFunc()}>Make interval call</button>;
}

export default App;

正如您在上面看到的,当用户按下按钮时,就会对我们的 /ping 端点进行 API 调用,并在清除间隔之前重试 7 次。有没有更有效的方法或者这已经足够好了?非常感谢您的反馈。

最佳答案

如果您在重试之前等待 ping 响应,我建议将 setInterval 更改为 setTimeout

这是因为除非清除,否则 setInterval 将继续按一定时间间隔运行。

这意味着,如果请求花费的时间比预期长,它可能会在下一个间隔开始后收到响应。

使用setTimeout将确保您在再次检查之前收到响应

import React from "react";
import axios from "axios";

function App() {
  const apiCall = async () => {
    try {
      const ping = await axios({
        url: "https://rest.ensembl.org/info/ping?content-type=application/json",
        method: "GET",
        headers: {
          accept: "Application/json",
          "Content-Type": "Application/json",
        },
      });
      return ping.data;
    } catch (error) {
      return error.response;
    }
  };

  const myIntervalFunc = () => {
    let myCall = async () => await apiCall();
    let retryNum = 0;
    
    // do you need to call this here?
    // it doesn't seem like this would do anything
    myCall();

    // create interval as a named function
    const interval = async () => {
        let intervalCall = await myCall();
        
        // end loop if ping === 2
        if (intervalCall.ping === 2) {
          return;
        }

        retryNum++;
        console.log("INTERVAL DATA ", intervalCall);
        
        // you don't need to change the `===` to `>=`
        // I find this is a `safe` way to handle it
        // in case something else increments retryNum
        // beyond 6 
        if (retryNum >= 6) {
          return;
        }

        // run `interval` again
        setTimeout(interval, 3000);
    };
    
    // call interval
    interval();
  };

  return <button onClick={() => myIntervalFunc()}>Make interval call</button>;
}

export default App;

关于javascript - 如何最好地利用 setInterval 来轮询 API 端点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64272899/

相关文章:

javascript - 将 axios 响应保存到状态 react Hook

javascript - react promise - TypeError : Cannot read property 'then' of undefined

javascript - 加载新页面时,toggleClass 会被删除

javascript - 整理对象数组中相同的键并对值求和 javascript

javascript - react native vs reactXP

reactjs - 使用 async componentDidMount() 好吗?

javascript - 在加载时无需事件即可将数据从子级传递到父级,这在 vue 世界中可能吗?

javascript - 在 asp.net 中使用 jquery 选项卡的 OnClick 函数

javascript - 如何获取用户访问的任何新网站的 URL?

javascript - 如何从数据库 firebase 获取推送 ID