Promise.all(): 여러 비동기 작업을 동시에 처리하기

KangWook·2025년 2월 19일
0

Promise.all(): 여러 비동기 작업을 동시에 처리하기

들어가며

현대 웹 개발에서 여러 비동기 작업을 효율적으로 처리하는 것은 매우 중요합니다. 특히 여러 API를 호출하거나, 다수의 파일을 처리해야 할 때 Promise.all()은 강력한 도구가 됩니다. 이번 글에서는 Promise.all()의 개념부터 실제 사용 사례까지 자세히 알아보겠습니다.

Promise.all()이란?

Promise.all()은 여러 프로미스를 병렬로 처리하고 모든 프로미스가 완료될 때까지 기다리는 메서드입니다. 배열로 전달된 모든 프로미스가 성공적으로 이행되면, 각 프로미스의 결과값을 배열로 반환합니다.

기본 문법

Promise.all([promise1, promise2, promise3])
  .then(results => {
    // results는 각 프로미스의 결과값을 담은 배열
  })
  .catch(error => {
    // 어느 하나라도 실패하면 에러 처리
  });

주요 특징

  1. 병렬 실행

    • 모든 프로미스가 동시에 실행됩니다.
    • 전체 실행 시간은 가장 오래 걸리는 프로미스의 실행 시간과 같습니다.
  2. 실패 처리

    • 하나의 프로미스라도 실패하면 전체가 실패로 처리됩니다.
    • 첫 번째 발생한 에러가 catch 블록으로 전달됩니다.
  3. 결과 배열

    • 결과는 입력된 프로미스 배열과 동일한 순서를 보장합니다.
    • 실행 완료 순서와 관계없이 입력 순서대로 결과가 저장됩니다.

실제 사용 예제

1. 여러 API 동시 호출

async function fetchUserData() {
  try {
    const [profile, posts, friends] = await Promise.all([
      fetch('/api/profile'),
      fetch('/api/posts'),
      fetch('/api/friends')
    ]);
    
    const results = await Promise.all([
      profile.json(),
      posts.json(),
      friends.json()
    ]);
    
    return {
      profile: results[0],
      posts: results[1],
      friends: results[2]
    };
  } catch (error) {
    console.error('데이터 로딩 실패:', error);
    throw error;
  }
}

2. 파일 처리

async function processMultipleFiles(files) {
  const filePromises = files.map(file => processFile(file));
  
  try {
    const results = await Promise.all(filePromises);
    console.log('모든 파일 처리 완료:', results);
  } catch (error) {
    console.error('파일 처리 중 오류 발생:', error);
  }
}

3. 이미지 프리로딩

function preloadImages(imageUrls) {
  const loadImage = url => {
    return new Promise((resolve, reject) => {
      const img = new Image();
      img.onload = () => resolve(img);
      img.onerror = () => reject(new Error(`Failed to load ${url}`));
      img.src = url;
    });
  };

  return Promise.all(imageUrls.map(loadImage));
}

주의사항과 팁

  1. 에러 처리

    • 항상 catch 블록을 사용하여 에러를 적절히 처리해야 합니다.
    • 개별 프로미스의 실패를 허용하려면 Promise.allSettled()를 고려하세요.
  2. 성능 고려

    • 너무 많은 프로미스를 동시에 실행하면 리소스 문제가 발생할 수 있습니다.
    • 필요한 경우 배치 처리를 고려하세요.
  3. 타임아웃 처리

function timeoutPromise(ms, promise) {
  const timeout = new Promise((_, reject) => {
    setTimeout(() => reject(new Error('Timeout')), ms);
  });
  
  return Promise.race([promise, timeout]);
}

// 사용 예제
const promises = [promise1, promise2, promise3];
Promise.all(promises.map(p => timeoutPromise(5000, p)))
  .then(results => console.log('모든 작업 완료:', results))
  .catch(error => console.error('작업 실패:', error));

마치며

Promise.all()은 여러 비동기 작업을 효율적으로 처리할 수 있게 해주는 강력한 도구입니다. 적절한 에러 처리와 함께 사용한다면, 복잡한 비동기 로직을 깔끔하게 처리할 수 있습니다. 특히 여러 API를 동시에 호출하거나 다수의 파일을 처리해야 하는 상황에서 큰 힘을 발휘합니다.

profile
꾸준히 성장하는 개발자

0개의 댓글