- Published on
Promise 관련 API 살펴보기
- Author
- Name
- yceffort
이 글을 번역 하고 요약했습니다.
name | description | |
---|---|---|
Promise.allSettled | does not short-circuit | this proposal 🆕 |
Promise.all | short-circuits when an input value is rejected | added in ES2015 ✅ |
Promise.race | short-circuits when an input value is settled | added in ES2015 ✅ |
Promise.any | short-circuits when an input value is fulfilled | separate proposal 🔜 |
Promise.all
Promise를 배열로 받을 수 있으며, 모두 실행이 끝나거나 이 중 하나라도 reject 되면 끝나게 된다.
유저가 버튼을 클릭했을 때, CSS를 모두 다운로드 해서 완전히 새로운 UI를 그려주는 스펙을 상상해보자.
const promises = [
fetch('/component-a.css'),
fetch('/component-b.css'),
fetch('/component-c.css'),
]
try {
const styleResponses = await Promise.all(promises)
enableStyles(styleResponses)
renderNewUi()
} catch (reason) {
displayError(reason)
}
모든 요청이 성공해야 렌더링이 필요할 것이다. 만약 여기에서 하나라도 오류를 뱉게 된다면, 다른 작업이 끝나는 것을 기다리지 않고 바로 종료한다.
Promise.race
Promise.race
는 여러 개의 promise를 실행시킬 때, 아래와 같은 상황에서 유용하다.
- 하나라도 먼저 끝나는 것을 원하는 경우
- 바로 Promise가 리젝트 되었을 때 실행되길 원하는 경우
즉, Promise 중 하나가 거부되면 즉시 오류를 개별적으로 처리하게 된다.
try {
const result = await Promise.race([
performHeavyComputation(),
rejectAfterTimeout(2000),
])
renderResult(result)
} catch (error) {
renderError(error)
}
위 예제에서는 시간이 오래 걸리는 연산을 수행하거나, 2초후에 리젝트 되는 함수와 경쟁을 한다. 성공 또는 실패 중 첫번째로 실행되는 결과에 따라서 결과 또는 오류메시지를 처리할 수 있다.
Promise.allSettled
Promise.allSettled
는 모든 Promise 들이 종료되면, 성공과 실패와 상관없이 실행된다.
이는 Promise의 성공 실패가 중요하지 않고 단순히 종료되는 것을 확인하고 싶을 때 유용하다. 예를 들어, 모든 Promise가 끝나고 나면 로딩 스피너를 없애는 케이스가 존재할 수 있다.
const promises = [
fetch('/api-call-1'),
fetch('/api-call-2'),
fetch('/api-call-3'),
]
await Promise.allSettled(promises)
// 성공 실패와 관련없이 모두 종료가 되면 실행된다.
removeLoadingIndicator()
Promise.any
Promise.any
는 Promise가 하나라도 실행이 종료되면 실행된다는 점이 Promise.race
와 유사하다. 다만 다른 점은, 하나가 실패한다고 해서 종료되지 않는다.
const promises = [
fetch('/endpoint-a').then(() => 'a'),
fetch('/endpoint-b').then(() => 'b'),
fetch('/endpoint-c').then(() => 'c'),
]
try {
const first = await Promise.any(promises)
// 첫번째로 성공한 Promise
console.log(first)
// → e.g. 'b'
} catch (error) {
// 모든 Promise가 거절될 경우
console.assert(error instanceof AggregateError)
// 실패한 값을 프린트 한다.
console.log(error.errors)
// → [
// <TypeError: Failed to fetch /endpoint-a>,
// <TypeError: Failed to fetch /endpoint-b>,
// <TypeError: Failed to fetch /endpoint-c>
// ]
}
Promise.any
에서 두 개 이상의 에러가 날 경우, 한번에 여러 에러들을 합칠 수 있는 AggregateError를 사용할 수도 있다.
Promise.any([Promise.reject(new Error('some error'))]).catch((e) => {
console.log(e instanceof AggregateError) // true
console.log(e.message) // "All Promises rejected"
console.log(e.name) // "AggregateError"
console.log(e.errors) // [ Error: "some error" ]
})