이번에는 비슷하면서도 다른 Promise.all과 Promise.allSettled에 대해서 알아보려고 합니다.
Promise.all은 여러 개의 프로미스를 동시에 실행하고, 모든 프로미스가 성공적으로 처리될 때까지 기다리는 메서드입니다.
이 메서드는 배열로 받은 프로미스들이 모두 이행(resolve)될 때까지 기다렸다가, 모든 프로미스의 결과값을 배열로 반환합니다. 하지만, 배열 중 하나의 프로미스라도 거부(reject)되면 Promise.all은 즉시 거부되고, 첫 번째 거부된 프로미스의 결과를 반환합니다.
다음은 Promise.all의 예제 코드인데 이 예제에서는 3개의 프로미스를 배열로 전달하고, 이행되는 시간을 조절하여 결과를 확인합니다.
const promise1 = Promise.resolve(1);
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => resolve(2), 1000);
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => reject("Error"), 2000);
});
Promise.all([promise1, promise2, promise3])
.then((results) => {
console.log(results); // [1, 2, "Error"]
})
.catch((error) => {
console.log(error); // Error
});
위의 예제 코드에서는 promise1은 즉시 이행되는 프로미스입니다. promise2는 1초 후에 이행되는 프로미스이며, promise3는 2초 후에 거부되는 프로미스입니다. Promise.all은 이 3개의 프로미스가 모두 처리될 때까지 기다린 다음, 결과값인 [1, 2, "Error"]를 반환합니다.
하지만 promise3이 2초 후에 거부되므로 catch 블록이 실행되어 "Error"를 출력합니다.
그럼 Promise.allSettled은 어떤 점이 차이가 다를까요?
Promise.allSettled는 Promise.all과는 다르게 모든 프로미스의 상태(성공 또는 실패)에 관계없이 모든 프로미스가 완료될 때까지 기다립니다.
Promise.allSettled는 배열로 받은 프로미스들이 모두 처리될 때까지 기다린 다음, 각 프로미스의 상태와 결과를 포함하는 객체의 배열을 반환합니다. 이 객체에는 프로미스가 이행된 경우 "status" 속성이 "fulfilled"로 설정되고, "value" 속성에 프로미스의 결과값이 할당됩니다. 반면 프로미스가 거부된 경우 "status" 속성은 "rejected"로 설정되고, "reason" 속성에 거부 이유가 할당됩니다.
이번에도 예제코드를 보면서 진행해보겠습니다. 이 예제에서도 마찬가지로 3개의 프로미스를 배열로 전달하고, 결과를 확인합니다.
const promise1 = Promise.resolve(1);
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => resolve(2), 1000);
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => reject("Error"), 2000);
});
Promise.allSettled([promise1, promise2, promise3])
.then((results) => {
console.log(results);
/*
[
{ status: "fulfilled", value: 1 },
{ status: "fulfilled", value: 2 },
{ status: "rejected", reason: "Error" }
]
*/
});
위의 예제 코드는 Promise.all의 예제코드를 Promise.allSettled로 바꾸어서 실행하는 코드입니다. 코드를 살펴보면 Promise.allSettled는 이 3개의 프로미스가 모두 처리될 때까지 기다린 다음, 각 프로미스의 상태와 결과를 객체로 포함하는 배열을 반환합니다.
위의 예제에서는 [promise1, promise2, promise3]의 순서대로 이행, 이행, 거부되므로 결과는 주석에 나와있는 대로 배열이 됩니다.
이렇게 Promise.all과 Promise.allSettled는 비동기 작업을 동시에 처리하고 결과를 반환하기 위해 사용됩니다.
Promise.all은 모든 프로미스가 성공적으로 처리될 때까지만 기다리므로, 실패한 프로미스가 있는 경우 전체 작업이 중단될 수 있습니다. 반면 Promise.allSettled는 모든 프로미스의 결과와 상태를 확인해야 하는 경우에 사용합니다.
Promise.all과 Promise.allSettled는 각각 다른 상황에 적합한 메서드이기 떄문에 어떤 게 더 좋냐라고 할 순 없지만 문맥과 목표에 따라 구분해서 사용하는 것이 좋습니다.
예를 들어 테스트를 할 때나 어떤 점에서 작업이 중단되는지 살펴볼 때는 Promise.all보다 Promise.allSettled를 사용하여 세부적으로 살펴볼 수 있고
실제로 작업을 하면서 여러 개의 비동기 작업 중 하나라도 실패하면 전체 작업을 중단해야 할 때는 Promise.all이 유용하다고 할 수 있습니다.