안녕하세요

Promise.all 여러개의 프로미스를 병렬로 실행한 결과를 배열로 반환 (Promise.allSettled) 본문

유튜브컨텐츠탐색-StelLife/MongoDB

Promise.all 여러개의 프로미스를 병렬로 실행한 결과를 배열로 반환 (Promise.allSettled)

sakuraop 2023. 3. 6. 03:33

Promise.all 이란

Promise.all 함수는 여러 개의 프로미스를 배열 형태로 받아 한 번에 실행하고,

전달된 프로미스들이 모두 완료될 때까지 기다린 후, 그 결과를 배열 형태로 반환해주는 함수입니다.

 

Promise.all 함수는 프로미스 배열을 받아서 하나의 프로미스를 반환하며,

=> 이 프로미스는 전달된 모든 프로미스가 resolve 될 때까지 기다린 다음,

=> 각각의 프로미스의 결과를 담은 배열로 resolve 됩니다.

 

***만약 전달된 프로미스 중 하나라도 reject 된다면,***

=> Promise.all은 해당 프로미스의 reject 값을 반환합니다.

 

이러한 특성으로 인해, Promise.all 함수는 여러 개의 프로미스가 병렬로 실행되어야 할 때 유용합니다.

Promise.all 함수를 사용하면 여러 개의 비동기 작업을 병렬로 실행할 수 있으므로,

전체 작업을 빠르게 처리할 수 있습니다.

 

예를 들어, 데이터베이스에서 여러 개의 쿼리를 한 번에 실행하고,

그 결과를 한 번에 처리해야 할 때 Promise.all 함수를 사용할 수 있습니다.


Promise.all 특징

Promise.all을 이용하면 여러 개의 비동기 작업을 동시에 처리할 수 있기 때문에, 작업 시간을 크게 줄일 수 있습니다.

 

예를 들어, 3개의 비동기 작업이 각각 1초, 2초, 3초가 걸린다면,

이 작업들을 순차적으로 실행하면 총 6초가 걸립니다.

그러나 Promise.all을 사용하면 이 3개의 작업을 모두 동시에 실행할 수 있기 때문에,

가장 오래 걸리는 작업이 끝날 때까지 기다리지 않아도 됩니다.

따라서, 이 경우에는 총 3초가 걸리게 됩니다.

 

  • 코드를 더 간결하고 가독성 높게 작성할 수 있습니다.
  • 코드의 중복을 줄일 수 있습니다. 여러 개의 비동기 작업을 하나의 배열로 묶어서 처리할 수 있기 때문.
  • 배열의 순서를 보장하므로, 여러 개의 작업의 결과를 순서대로 처리할 때 유용합니다.

 

하지만, Promise.all을 사용할 때에는 작업 중 하나라도 실패할 경우 전체 작업이 실패하게 되는 단점이 있습니다.

 

이 경우에는 Promise.allSettled를 사용하면,  모든 작업이 완료될 때까지 기다리고,

모든 작업의 결과를 확인할 수 있습니다.

 

Promise.allSettled

Promise.allSettled는 여러 개의 프로미스를 동시에 실행하고,

각각의 프로미스가 fulfilled(이행) 또는 rejected(거부) 상태가 될 때까지 모든 작업이 완료될 때까지 기다린 후,

모든 프로미스의 결과를 확인할 수 있도록 도와주는 메서드입니다.

 

Promise.all과 다르게, Promise.allSettled는 모든 프로미스가 처리되었을 때,

각각의 프로미스의 처리 결과(fulfilled인지, rejected인지)와 함께 결과 배열을 반환합니다.

따라서, 모든 프로미스의 처리 결과를 확인할 수 있습니다.

[
  { status: "fulfilled", value: 1 },
  { status: "rejected", reason: "error" },
  { status: "fulfilled", value: 3 },
]

위와 같이 배열 안에 각각의 객체 요소가 status와 결과를 반환 받습니다.

status: "fulfilled" 인 경우에는 data가,

status: "rejected" 인 경우에는 reason에는 reject된 이유가 담깁니다.


    const channels = await db.collection("channels");
    const playlists = await db.collection("playlists");

    const members = await Promise.all(
      memberIds.map(async (id) => {
        const channel = await channels.findOne({ channelId: id });
        const playlist = await playlists.findOne({ channelId: id });
        channel.latestVideo = playlist.videos[0];
        return channel;
      })
    );

members 에는 각각의 map 함수를 통해서

channel에 channels collection에서 찾은 데이터가 담기고,

playlists collection에서 찾은 데이터 중 videos[0] 프로퍼티를 channel.latestVideo 프로퍼티에 할당했다.

 

map의 순회가 끝나게 되면 playlist.videos[0]이 channel에 추가가 된 Promise 결과를 담은 배열이 

members에 할당이 된다.

 

members // [ data1, data2, data3, data4 ]