나의 개발 일지

로딩 및 예외처리 vanilla JS로 만들어보기 (Pending, Fulfilled, Failed)

designer DK 2024. 11. 17. 22:54
728x90

쇼핑몰 프로젝트를 해보면서 서버 호출을 많이 함에 따라

로딩 및 예외처리도 중요하겠다고 느껴졌다.

 

강의를 봤을 때도 Pending, Fulfilled, Failed 세 케이스를 체계적으로 관리하는 부분이 나왔는데

나도 향후 프로젝트 부터는 이 부분을 체계적으로 관리해보고자 vanilla JS로 이 부분을 관리하는 방법을 gpt와 연구해보았다.

 

fetchUtils.js라는 파일을 만들어주고

그 파일 안에 있는 fetchWithStatus라는 함수를 통해 모든 fetch와 그에 따른 status를 관리하는 방식이다.

(html에서 추가로 불러와야 함)

 
async function fetchWithStatus(url) {
const status = {
pending: true,
fulfilled: false,
failed: false,
data: null,
error: null,
};

try {
const response = await fetch(url);
if (!response.ok) throw new Error('Network error');
 
const data = await response.json();

status.pending = false;
status.fulfilled = true;
status.data = data;
} catch (error) {
status.pending = false;
status.failed = true;
status.error = error.message;
}

return status;
}

 

함수가 실행되면 status라는 객체가 생성되는데

기본적으로 Pending이 ture 상태이며

리스폰스를 성공적으로 받아오면 fulfilled가 true가 되고

에러가 발생하면 failed가 true가 되는 방식의 함수이다.

 

이를 이용해서 admin쪽 get 함수를 예외처리 관리 방식으로 코드를 바꿔보았다.

let currentPage = 1; // 현재 페이지를 추적

// 상품 읽기
async function getProducts(page = 1) {
const searchInput = document.getElementById("search-input").value.trim();
const query = encodeURIComponent(searchInput); // 검색어 인코딩
const itemListContainer = document.getElementById("item-list-container");

// 기존 컨텐츠 초기화
itemListContainer.innerHTML = "<h1>Loading...</h1>";

// **인위적으로 지연 추가 (예: 2초)**
await new Promise((resolve) => setTimeout(resolve, 1000));

// API 호출
const status = await fetchWithStatus(`${URI}/api/product?page=${page}&name=${query}`);

// 로딩 중 메시지 제거
itemListContainer.innerHTML = "";

// 상태에 따른 처리
if (status.pending) {
itemListContainer.innerHTML = "<h1>Loading...</h1>";
return;
}

if (status.failed) {
itemListContainer.innerHTML = `<p style="color: red;">Error: ${status.error}</p>`;
return;
}

// 상품이 없을 때
if (status.fulfilled && status.data.data.length === 0) {
itemListContainer.innerHTML = "<p>상품 목록이 없습니다.</p>";
return;
}

// 상품 있을 때
-------------기존 fetch 코드----------------------

// 페이지네이션 추가
createPagination(status.data.totalPageNum);
}

 

코드를 보면 기본적으로 html에 로딩을 넣어주며

fetchWithStatus(url) 함수에 요청 주소를 넣어서 바로 API를 호출한다.

호출이 되면 그에 따른 status처리가 이루어지는데

pending일 때는 로딩을 넣어주고

failed일 때는 에러메시지,

상품이 없을 때는 상품이 없다는 메시지를 넣어준다.

상품이 있는 경우, 즉 fulfilled의 경우 기존 코드에서 진행했던 모든 작업이 수행되면 된다.

 

이렇게 하면 많은 api 함수에 대해 체계적으로 예외처리 관리를 할 수 있을 듯 하다.