Promise.race를 사용하여 API Timeout 구현하기

엔케이·2025년 2월 12일
0
post-thumbnail

Promise.race를 사용하여 API Timeout 구현하기

API 호출 시, 네트워크 지연이나 서버 문제로 인해 응답이 오지 않는 상황이 발생할 수 있습니다. 이러한 문제를 방지하기 위해 타임아웃을 설정하여 일정 시간이 지난 후 요청을 강제로 종료할 수 있습니다. 이번 포스트에서는 Promise.race를 이용하여 간단하게 API 타임아웃을 구현하는 방법에 대해 알아보겠습니다.

Promise.race란?

Promise.race는 전달된 프로미스 배열 중 가장 먼저 완료되는 프로미스의 결과를 반환합니다.

이를 활용하면, 여러 프로미스 중 하나가 먼저 완료되는 시점을 기준으로 로직을 작성할 수 있습니다.

예를 들어, API 요청과 타임아웃 프로미스를 동시에 실행하여, 둘 중 먼저 완료되는 것을 기준으로 성공/실패를 판단할 수 있습니다.

API Timeout 구현

아래 예제에서는 fetch 요청과 타임아웃 프로미스를 Promise.race로 경합시켜, 만약 일정 시간 내에 fetch 요청이 완료되지 않으면 타임아웃 에러를 발생시키도록 구현했습니다.

/**
 * fetch 요청에 타임아웃을 적용하는 함수
 * @param {string} url - 요청할 API 엔드포인트
 * @param {Object} [options={}] - fetch 옵션
 * @param {number} [timeout=5000] - 타임아웃 시간 (밀리초 단위)
 * @returns {Promise<Response>}
 */
function fetchWithTimeout(url, options = {}, timeout = 5000) {
  // 타임아웃 프로미스: 지정된 시간 후에 reject 발생
  const timeoutPromise = new Promise((_, reject) => {
    const id = setTimeout(() => {
      clearTimeout(id);
      reject(new Error('요청 시간이 초과되었습니다.'));
    }, timeout);
  });

  // fetch 요청과 타임아웃 프로미스를 경합시킴
  return Promise.race([
    fetch(url, options),
    timeoutPromise
  ]);
}

코드 설명

  1. 타임아웃 프로미스 생성

    • new Promise((_, reject) => { ... })를 사용하여 지정된 시간(timeout 밀리초) 후에 reject 하는 프로미스를 생성합니다.
    • setTimeout 함수로 타이머를 설정하고, 타이머가 만료되면 에러 메시지를 반환합니다.
  2. Promise.race를 통한 경합

    • Promise.racefetch 요청과 타임아웃 프로미스를 배열 형태로 전달합니다.
    • 두 프로미스 중 먼저 완료된 결과가 반환됩니다.
      • 만약 fetch가 빠르게 완료되면 해당 응답을 반환합니다.
      • 반대로 fetch가 지정된 시간 내에 완료되지 않으면 타임아웃 프로미스가 먼저 reject되어 에러가 발생합니다.
  3. 사용 예시

    fetchWithTimeout('https://api.example.com/data', {}, 3000)
      .then(response => {
        if (!response.ok) {
          throw new Error('네트워크 응답에 문제가 있습니다.');
        }
        return response.json();
      })
      .then(data => {
        console.log('API 응답 데이터:', data);
      })
      .catch(error => {
        console.error('에러 발생:', error);
      });
    

주의 사항

  • 타임아웃 후 처리: 타임아웃이 발생하면 fetch 요청은 여전히 진행 중일 수 있습니다. 만약 네트워크 요청 자체를 취소하고 싶다면, AbortController를 사용하여 요청을 취소하는 방법을 고려할 수 있습니다.
  • 사용 환경: 이 예제는 브라우저 환경에서 사용 가능한 fetch API를 기반으로 작성되었습니다. Node.js 환경에서는 node-fetch 등을 사용하여 유사하게 구현할 수 있습니다.

결론

Promise.race를 사용하면 간단하고 직관적으로 API 요청에 타임아웃을 적용할 수 있습니다.

특정 시간 내에 응답이 없을 경우 자동으로 에러를 발생시키므로, 사용자 경험 개선 및 예외 상황 처리가 용이해집니다.

여러분도 이번 예제를 참고하여 다양한 네트워크 요청 상황에 맞게 타임아웃 로직을 적용해 보시기 바랍니다.

Happy Coding!


profile
FE 개발자

0개의 댓글