SetTimeout бесконечное l oop и запускать функцию один раз - PullRequest
1 голос
/ 04 августа 2020

Мне нужно уменьшить количество сетевых вызовов от функции setInterval. Каждые 3 секунды вызывается API. Первому API иногда требуется больше времени для получения ответа от сервера.

Код

useEffect(() => {
 const id = setInterval(async () => {
  console.log('hello')
  await callAPI()
  console.log('bye')
 }, 3000);
 return () => {
  clearInterval(id);
 };
})

Проблема

Функция setInterval вызывает метод callAPI каждые 3 секунды, в то время как метод API первого вызова все еще работает в ожидании ответа сервера, что приводит к множеству вызовов API, которые рассылают сервер спамом. 1017 * Функция SetInterval должна дождаться ответа первого вызываемого метода перед повторным запуском метода каждые 3 секунды.

1 Ответ

1 голос
/ 04 августа 2020

Я бы просто использовал setTimeout, который вызывает сам себя:

useEffect(async () => {
 let id;
 const api = async () => {
    console.log('hello')
    await callAPI()
    console.log('bye')
    id = setTimeout(api, 3000);
 });
 await api();
 return () => {
  clearTimeout(id);
 };
})

Например:

const api = () => {
    console.log('hi');
    setTimeout(api, 1000);
    console.log('bye');
}

api();

    const Example = props => {
      const [countdown, setCountdown] = React.useState(100);
      React.useEffect(() => {
          const timeout = setTimeout(() => {
              setCountdown(countdown - 1);
          }, 1000);
          return () => {
              clearTimeout(timeout);
          }
      }, [countdown]);
      
      return (<div>{countdown}</div>)
    }


    // Render it
    ReactDOM.render(
      <Example />,
      document.getElementById("react")
    );
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>

    <div id="react"/>
...