본문 바로가기
C.W.K.
Stream
Lesson 04 of 05 · published

`Promise.all`: 병렬 결과의 자리 보존하기

~8 min · async-promises, promise-all, tuples, concurrency

Level 0Curious
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete
"함께 시작한 작업은 함께 기다리되, 각 결과가 어느 자리에서 왔는지 잃지 마."

튜플 입력이면 튜플 결과

Promise.all([loadUser(), loadSettings()])의 입력이 고정된 튜플로 추론되면 결과도 [User, Settings]처럼 자리별 타입을 보존해. 구조 분해한 usersettings가 각각 정확한 타입을 갖는 이유야.

병렬성은 호출 시점에서 시작된다

Promise를 만드는 함수가 즉시 작업을 시작한다면 배열을 만든 순간 요청들이 출발해. firstsecond를 차례로 기다리면 순차 실행이야. Promise.all([first(), second()])로 기다리면 독립 작업을 겹쳐 실행할 수 있어.

하나의 거절과 나머지 작업

입력 중 하나가 거절되면 반환 Promise도 바로 거절돼. 모두의 성공과 실패를 각각 모아야 한다면 Promise.allSettled를 써.

순차 호출과 병렬 호출의 차이는 performance.now()로 직접 재 봐. 세 요청이 서로 의존하지 않는다면 Promise.all이 전체 대기 시간을 줄이면서 튜플 위치별 타입도 보존해.

Promise.all은 서로 독립적인 유한 작업을 병렬로 기다리고 결과의 자리를 보존하는 도구야. 동시성 한도와 취소 정책은 별도로 책임져.

Code

병렬 vs 순차, 타입-안전 tuple 과 함께·typescript
// 순차 — 느림.
async function loadSequential() {
  const user = await fetchUser(1);        // 기다림
  const posts = await fetchPosts(1);      // 그다음 또 기다림
  return { user, posts };
}

// 병렬 — Promise.all 이 tuple typing 보존.
async function loadParallel() {
  const [user, posts] = await Promise.all([
    fetchUser(1),
    fetchPosts(1),
  ]);
  // user: User, posts: Post[] — 위치별 타입 보존
  return { user, posts };
}

// Promise.allSettled — 실패 포함 모든 결과 수집.
async function loadResilient() {
  const results = await Promise.allSettled([fetchUser(1), fetchPosts(1)]);
  // results: [PromiseSettledResult<User>, PromiseSettledResult<Post[]>]
  for (const r of results) {
    if (r.status === 'fulfilled') console.log(r.value);
    else console.error(r.reason);
  }
}

External links

Exercise

서로 독립적인 세 요청을 순차 실행에서 Promise.all로 바꾸고 시간을 비교해. 하나를 실패시켜 전체 결과와 오류가 어떻게 달라지는지도 관찰해.
Hint
순차 실행 시간은 각 작업 시간의 합에 가깝고, 병렬 실행은 가장 오래 걸린 작업의 시간에 가까워.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.