본문 바로가기
front-end/Code refactoring

Promise.all을 활용하여 비동기 코드 작성하기

by 행인데어 2024. 3. 5.

현재 진행 중엔 프로젝트에서 비동기 로직을 개선/수정하는 사항이 생겼다.

그래서 Promise.all을 처음 사용하게 되었는데 아직도 내가 모르는 것이 정말 많다고 느꼈다.

 

문제 상황

배열을 순환하면서 배열의 값을 parameter로 api를 여러번 호출시켜야 하는 상황

 

해결 방안

검색 결과 “배열을 순환하면서 배열의 값을 parameter로 넣어 api를 여러번 반복적으로 호출”

하기 위해 Promise.all을 사용하는 것이 좋다고 판단했다

 

1. 첫번째 시도

fetchAbsolute가 promise를 반환해서 이걸 처리하는데 문제가 있는듯 했다.

즉, fetchAbsolute의 result를 끝까지 기다리도록 만들어야 하는 문제가 생겼다.

const fetchData = async (param1, param2) => {
  const apiUrl = `/getData?param1=${param1}&param2=${param2}`;
  return fetchAbsolute("post", apiUrl);
};


useEffect(()=>{
      const itemResults= await Promise.all(
        list.map((data) =>
          fetchData(data.param1, data.param2)
        )
      );

	setData[...itemResults];
},[list])

 

2. 두번째 시도

‘fetchData’함수에서 Promise.all을 사용하여 map함수 안에서 각각의 api 호출을 기다리도록 수정했다.

const fetchData = async (list) => {
	let totalList = [];

  await Promise.all(
    list.map(async (data) => {
	   try {
			const result = await fetchAbsolute(
         "post",
					`/getData?param1=${data.param1}&param2=${data.param2}`,
					{ 
						data: { ~~ }
					}
				)
			 if (result.error) throw new Error("오류 발생");
				totalList = [...totalList, ...result.data.list];
			} catch (error) {
        // Handle error for individual API call
        alert("오류 발생");
      }
		}
	)
};


useEffect(()=>{
      const itemResults= await Promise.all(
        list.map((data) =>
          fetchData(data.param1, data.param2)
        )
      );

	setData[...itemResults];
},[list])

 

처음에 “배열을 순회하면서 배열의 값을 parameter로 api 여러개를 반복 호출”해야 할 때

Promise.all을 쓰면 된다는 것을 전혀 생각하지 못했다.

그래서 Promise.all을 사용할 수 있는 경우에 대해 정리해 보았다.

 

Promise.all을 사용할 수 있는 케이스

1. 병행하는 작업있을 때

independent asynchronous task들이 동시에 수행되고,

모든 task들이 다음 작업으로 넘어 가기전에 compelete되기를 기다려야 할때

ex) performance를 개선시키고, 전반적인 reponse 시간을 줄이기 위해 다양한 api로부터 동시에 데이터를 받아올 때

 

2. 처리 과정을 묶을 때

많은 데이터 묶음을 비동기적으로 처리하고, 다음 action을 수행하기 전에 모든 작업을 완료할 때까지 기다릴 때

ex) 유저에 의해 많은 파일, 이미지를 처리하고, 모든 파일이 처리되었다는 것을 유저에게 알리는 경우

 

3. API 호출을 여러번할 때

다른 api를 여러번 호출하고 유저에게 result를 보여주기 전에 합칠 때

ex) 각각 다른 api로부터 유저 프로필 데이터, 포스팅, 코멘트를 불러와서 하나의 화면에 합쳐서 보여줄때

 

요약하면, 다양한 비동기적인 독립 작업들이 있을 때 작업들이 동시에 수행되고 그들이 끝나기를(complete 되길) 기다릴 때 사용

 

Promise.all의 특징

  1. 각각의 작업이 서로 관계없는 독립적인 작업일 때 사용
  2. Promise.all은 모든 Promise를 병렬로 실행 → 순서가 상관없을 때 사용해야함
  3. Promise 함수 중 단 하나의 작업이라도 수행되지 않는다면 모든 작업이 종료 되므로 에러처리에 단점이 있다