
API 호출 시, 네트워크 지연이나 서버 문제로 인해 응답이 오지 않는 상황이 발생할 수 있습니다. 이러한 문제를 방지하기 위해 타임아웃을 설정하여 일정 시간이 지난 후 요청을 강제로 종료할 수 있습니다. 이번 포스트에서는 Promise.race를 이용하여 간단하게 API 타임아웃을 구현하는 방법에 대해 알아보겠습니다.
Promise.race는 전달된 프로미스 배열 중 가장 먼저 완료되는 프로미스의 결과를 반환합니다.
이를 활용하면, 여러 프로미스 중 하나가 먼저 완료되는 시점을 기준으로 로직을 작성할 수 있습니다.
예를 들어, API 요청과 타임아웃 프로미스를 동시에 실행하여, 둘 중 먼저 완료되는 것을 기준으로 성공/실패를 판단할 수 있습니다.
아래 예제에서는 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
]);
}
타임아웃 프로미스 생성
new Promise((_, reject) => { ... })를 사용하여 지정된 시간(timeout 밀리초) 후에 reject 하는 프로미스를 생성합니다.setTimeout 함수로 타이머를 설정하고, 타이머가 만료되면 에러 메시지를 반환합니다.Promise.race를 통한 경합
Promise.race에 fetch 요청과 타임아웃 프로미스를 배열 형태로 전달합니다.fetch가 빠르게 완료되면 해당 응답을 반환합니다.fetch가 지정된 시간 내에 완료되지 않으면 타임아웃 프로미스가 먼저 reject되어 에러가 발생합니다.사용 예시
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!