내일배움캠프 React_7기 TIL - 31. Promise.all

·2024년 11월 21일
1

Promise.all

병렬 데이터를 fetching

Promise.all은 JavaScript에서 제공하는 Promise 메서드로, 여러 개의 Promise를 병렬적으로 처리하고, 모든 Promise가 성공적으로 완료되었을 때 하나의 결과를 반환한다.

  • 모든 Promise가 완료되면 배열 형태의 결과값이 반환된다.
  • 하나의 Promise라도 실패하면 전체가 reject된다.

사용 시점

  • 여러 비동기 작업을 병렬로 처리할 때.
  • 서로 독립적인 비동기 작업 결과를 한꺼번에 받아야 할 때.
  • React에서는 주로 데이터 fetching 작업에서 사용된다.

사용법


Promise.all([promise1, promise2, promise3])
  .then((results) => {
    console.log(results); // 모든 Promise의 resolve 결과가 배열로 반환
  })
  .catch((error) => {
    console.error(error); // 하나라도 실패하면 해당 에러 출력
  });

주의 사항

  1. 하나의 Promise라도 실패하면 전체가 실패로 간주되므로, 개별 실패를 처리하려면 Promise.allSettled을 사용하는 것이 적합하다.
  2. 데이터 의존성이 있는 경우에는 Promise.all보다 체인 방식이나 async/await을 활용해야 한다.
  3. React에서는 데이터를 병렬로 가져오더라도, 상태 업데이트는 비동기로 처리되므로 리렌더링 타이밍을 고려해야 한다.

Promise.all 활용 : 데이터 매핑 작업

아래는 내가 이번 프로젝트에서 활용했던 코드이다.


const postsWithUserProfiles = await Promise.all(
  posts.map(async (post) => {
    const { data: userProfile, error: userProfileError } = await supabase
      .from("user_profiles") // Supabase의 "user_profiles" 테이블에서
      .select("id, username, profile_image_url") // 필요한 필드 선택
      .eq("id", post.user_id) // 현재 post의 user_id와 일치하는 프로필 찾기
      .single(); // 단일 결과만 반환

    if (userProfileError) {
      console.error(`Error fetching user profile for post ${post.id}:`, userProfileError);
      return { ...post, userProfile: null }; // 에러가 있으면 프로필 없이 반환
    }

    return { ...post, userProfile }; // 성공하면 프로필 데이터를 병합
  })
);
  • posts.map:
    • posts 배열의 각 요소(게시물)에 대해 비동기 작업(supabase.from)을 실행한다.
    • postuser_id를 기준으로 "user_profiles" 테이블에서 데이터를 조회한다.
  • Promise.all:
    • posts.map은 각 게시물에 대한 비동기 작업(post.user_id로 프로필 조회)을 Promise 배열로 반환한다.
    • Promise.all은 이 배열을 병렬로 처리하고, 모든 Promise가 완료되면 결과를 배열로 반환한다.
  • 결과 구조: 최종적으로 postsWithUserProfiles는 다음과 같은 구조를 가진 배열이다
      [
        {
          id: 1,
          title: "Post 1",
          user_id: 101,
          userProfile: {
            id: 101,
            username: "user_101",
            profile_image_url: "url_101"
          }
        },
        {
          id: 2,
          title: "Post 2",
          user_id: 102,
          userProfile: null // 프로필 가져오기 실패 시 null
        }
      ]
      

장점

  • Promise.all을 사용해 병렬 처리를 수행하므로, 각 게시물마다 사용자 프로필을 순차적으로 가져오는 것보다 속도가 빠르다.
  • async/await와 함께 사용하여 가독성 높은 코드를 작성할 수 있다.

주의점

  1. 병렬 처리의 부하:
    • posts의 길이가 매우 길면 많은 비동기 요청이 한 번에 실행되므로 서버에 부하가 갈 수 있다.
    • 이 경우 배치 처리(Chunking) 방법을 고려해야 한다.
  2. 개별 에러 처리:
    • Promise.all은 하나의 Promise라도 실패하면 전체가 실패로 간주된다. 하지만 이 코드는 개별적으로 error를 처리하므로 전체 중단을 방지한다.
profile
내배캠 React_7기 이수중

1개의 댓글

comment-user-thumbnail
2024년 11월 21일

뿌라미수~ (약속해줘~)

답글 달기

관련 채용 정보