API 폴링하기 위해 setInterval 활용하기

박은정·2023년 1월 9일
0

TIL

목록 보기
59/72

해당 스택오버플로우의 내용을 번역하며 나름대로 이해하려했습니다.

질문

원하는 응답을 받을 때까지 여러 번 호출하고 싶은 엔드포인트가 있는데, 이 접근 방식이 이를 처리하는데 효과적인 방법인지 알고 싶습니다.

그래서 이 엔드포인트를 /ping이라고 했을때, 이러한 { ping: 1} 객체를 반환합니다. 이제 이 엔드포인트를 몇 번 더 클릭하거나 ping값이 1에서 2로 변경할 때까지 클릭합니다. 이게 제가 지금 하고 있는 방법인데, 잘 맞지 않는 것 같습니다.

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

export default () => {
  const apiCall = async () => {
    try {
      const { data } = await axios.get("/ping");
      return data;
    } catch (err) {
      return err.response;
    }
  };

  const myIntervalFunc = () => {
    const myCall = async () => await apiCall();
    let retryNum = 0;
    myCall(); // 여기서 호출하는건 아무런 의미가 없는것같다
    
    const interval = setInterval(async () => {
      const intervalCall = await myCall();
      if (interval.ping !== 2) {
        retryNum = retryNum + 1;
        console.log("INTERVAL DATA", intervalCall);
      }
      if (retryNum === 6) clearInterval(interval);
    }, 3000);
  };
  return <button onClick={myIntervalFunc}>Make Interval Call</button>;
};

위처럼 사용자가 버튼을 누르면 /ping 엔드포인트로 API 호출이 이루어지며, interval을 지우기 전에 7번 재시도를 합니다.

대답

다시 시도하기 전에 ping이 응답하기를 기다리고 있다면 setInterval에서 setTimeout으로 변경하는 것이 좋습니다.

왜냐하면, setIntercal이 지워지지 않는 한 일정한 간격으로 계속 실행되기 때문에 요청이 예상보다 오래 걸릴 경우 다음 간격이 시작한 후 잠재적으로 응답을 수신할 수 있습니다.

setTimeout을 사용하면 다시 확인하기 전에 응답을 받을 수 있습니다.

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

export default () => {
  const apiCall = async () => {
    try {
      const { data } = await axios.get("/ping");
      return data;
    } catch (error) {
      return error.response;
    }
  };

  const myIntervalFunc = () => {
    const myCall = async () => await apiCall();
    let retryNum = 0;

    // 명명된함수로 interval 생성
    const interval = async () => {
      const intervalCall = await myCall();

      // ping이 2가 되면 루프 종료
      if (intervalCall.ping === 2) return;
      retryNum = retryNum + 1;
      console.log("INTERVAL DATA", intervalCall);

      if (retryNum >= 6) return;
      setTimeout(interval, 3000);
    };

    interval();
  };

  return <button onClick={myIntervalFunc}>Make Interval Call</button>;
};
profile
새로운 것을 도전하고 노력한다

0개의 댓글