Tip

JS 유용한 Promise활용

Kir93 2022. 2. 3. 19:19
728x90
반응형

ES2015에서 Promise.all, Promise.race가 나온 뒤, ES2020에서 Promise.allsettled가 나왔다.

그리고 Promise.any가 새로 나왔다.

위 4가지를 간단하게 비교해보려 한다.

Promise.all([success(), fail()]) // Error
Promise.race([fail(), delay(5000)]) // Error
Promise.allsettled([success(), fail()]) // success, Error
Promise.any([delay(5000), fail()]) // delay

간단하게 비교한다면 위와 같다.

먼저 가장 먼저 나온 all, race에 대해 말하자면,

1. Promise.all

Promise.all은 아무리 많은 양의 Promise들이 성공하더라도 단 하나의 Promise라도 rejected가 된다면 실패한다.

그래서 주로 초기 로딩과 같은 상황에서 여러 api요청을 보낼 때 병렬 처리로 보내 시간 단축을 노릴 때 많이 사용한다.

const apis = [
  fetch("/test/a").then(() => "a"),
  fetch("/test/b").then(() => "b"),
  fetch("/test/c").then(() => "c"),
];

try {
  await Promise.all(promises);
} catch (error) {
  throw new Error(error);
}

2. Promise.race

Promise.race는 Promise.all과 달리 fullfiled와 rejected를 가리지 않고 가장 먼저 Promise가 종료되면 끝이 난다.

개인적으로 본인은 자주 사용하지 않는데, 이 글을 작성하며 활용성을 생각한다면, api요청 결과의 제한시간을 두는 방법으로 사용할 수 있다.

const timeouts = [
  fetch("/test/a").then(() => "a"),
  setTimeout(() => {
    reject('5sec timeout!');
  }, 1000);
];

try {
  await Promise.race(timeouts);
} catch (error) {
  throw new Error(error); // 5sec timeout!
}

3. Promise.allsettled

Promise.all을 사용하며 가장 바란 함수다.

fullfiled와 rejected를 가리지 않고 모두 끝나면 종료되며 all과 같이 초기 로딩 등의 상황에서 api를 병렬로 처리할 때 유용하며, 성공 실패를 가리지 않는다는 점에서 다른 api들의 성공 여부에 독립적이다.

const apis = [
  fetch("/test/a").then(() => "a"),
  fetch("/test/b").then(() => "b"),
  fetch("/test/c").then(() => "c"),
];

try {
  await Promise.allsettled(promises);
} catch (error) {
  throw new Error(error);
}

4. Promise.any

Promise.race와 거의 비슷하며 다른 점이라면 Promise.race는 fullfiled와 rejected를 가리지 않는다는 것이고, any는 rejected는 무시하고 가장 먼저 fullfiled 된 요소를 체크한다.

그래서 주로 하나의 이미지 등을 여러 cdn등에서 불러오고 가장 먼저 로드된 이미지를 보여주는 식으로 활용할 수 있다.

const apis = [
  fetch("/test/a").then(() => "a"),
  fetch("/test/b").then(() => "b"),
];

try {
  const img = await Promise.any(promises);
} catch (error) {
  throw new Error(error);
}

ps. allsettled는 ES2020에서 들어온 요소이고 any는 ES2021에서 들어온 요소로 자신의 babel설정 등을 확인하여 사용하길 바란다.

 

반응형