본문 바로가기
자바스크립트

Promise.all VS Promise.allSettled (유사 멀티 스레딩)

by Devry 2023. 11. 28.

면접에서 직접 들은 질문인 Promise.all과 Promise.allSettled에 대해 정리를 하려고 한다. 내가 들었던 질문은

“Node.js는 싱글 스레드인가요, 멀티 스레드인가요?”에 대한 꼬리 질문으로 “자바스크립트는 Promise.all, Promise.allSettled로 멀티 스레딩을 흉내 내는데 그 차이를 알고 있습니까?” 였었다.

Promise 객체가 3가지 상태가 있고 resolve, reject 정도만 준비 해왔던 나는 간단하게 모른다는 답변을 하고 넘어갔다. 면접은 탈락했지만 이 질문이 얼마나 비중이 있는지는 알 수 없으니, 다른 동기 분들에게 물어봤는데 역시 처음 듣는다고 하였다.

나중에 알았지만 비교적 최근인 ES2020에서 추가된 문법이고, 그 회사의 특성상 비동기 요청을 병렬로 요청하는 로직이 많기 때문에 물어봤던 것 같다.

Promise.all

Promise 여러 객체를 병렬로 실행하는 메서드로, 하나의 Promise라도 reject가 되었다면 즉시 에러가 반환되고 나머지 Promise도 실행은 되지만 결과는 무시된다.

논리연산으로 본다면 모든 값이 true여야 true를 반환하는 and가 떠오른다

const promise1 = new Promise((resolve) => {
  setTimeout(() => {
    resolve(1);
  }, 3000);
});

const promise2 = new Promise((resolve) => {
  setTimeout(() => {
    resolve(2);
  }, 2000);
});

const promise3 = Promise.reject(new Error('에러'));

Promise.all([promise1, promise2, promise3])
  .then((result) => console.log(result))
  .catch((e) => console.error(e));

이 코드의 결과는 "Error: 에러"가 출력되고 나머지 결과는 얻을 수 없다.

단점

나머지 결과가 무시된다는 점에서 상당한 문제가 있음을 알 수 있다.

다수의 api 요청을 Promise.all로 처리 했을 경우, 하나의 reject라도 발생하면 Errror가 발생하는 문제점이 있었다.

Promise.allSettled

이러한 문제점을 해결하는 방법으로 ES2020에서 도입된 Promise.allSettled 메서드가 있다.

대부분의 형태는 Promise.all과 같고 reject 요청이 존재해도 결과를 반환한다.

const promise1 = new Promise((resolve) => {
  setTimeout(() => {
    resolve(1);
  }, 3000);
});

const promise2 = new Promise((resolve) => {
  setTimeout(() => {
    resolve(2);
  }, 2000);
});

const promise3 = Promise.reject(new Error('에러'));

Promise.allSettled([promise1, promise2, promise3]).then((results) => {
  results.forEach((result) => {
    console.log(result);
  });
});

실행의 결과로 fullfilled 상태는 value 값이, rejected 된 상태에는 reason에 에러가 있는 것을 알 수 있다

Promise.all만 사용할 때와 달리, Promise.allSettled를 사용하면 여러 병렬 처리를 한 결과 중에, 실패한 요청에 대해서만 따로 작업을 하는 것이 가능해진다.

이제는 둘의 차이를 알게 되어 면접에서 답변을 할 수 있게 되었다

하지만 아직도 궁금한 점은 promise.all로 멀티 스레딩과 비슷하게 동작한다는 의미인데, 싱글 스레드에서 어떻게 멀티 스레딩을 처리하는 것일까?

Promise.all은 어떻게 병렬 처리를 할까

위의 블로그와 MDN 공식 문서를 읽었지만 충분한 이해가 되지 않았고 대략적인 설명을 하면 Promise.all이 직접 실행에 관여하진 않고

상태만 감시한다는 것이다. 객체를 선언했을 때 이미 실행되고 타이머가 완료되었을 때 반환하므로 병렬처리하는 것처럼 보인다고 이해했다.

결론

Promise에 대해 공부하면서 메서드가 생각보다 많은 걸 알 수 있었고 자바스크립트는 빠르게 발전 중이다

기술 면접에서 모든 질문에 답변을 할 순 없겠지만 최신 문법에도 관심을 갖고 공부해야 한다

새로운 문법이 추가될 때마다 MDN을 열어본다면 알 수 있었겠지만, 직접 사용할 경험이 부족한 신입이 대답하기는 힘든 질문이 맞다.

Promise.all과 Promise.allSettled의 차이
Promise.all은 어떻게 병렬 처리를 할까
mdn web docs - Promise.allSettled()

'자바스크립트' 카테고리의 다른 글

[Javascript 문법] var, let, const 차이, 사용법  (2) 2022.12.04
[Redux] 사용법  (0) 2021.08.17

댓글