Promise 객체에는 비동기 작업을 동시에 처리하기 위한 동시성 정적 메서드
가 있습니다. 아래 정적 메서드를 사용하면 비동기 작업을 다양한 상황에 따라 처리할 수 있습니다.
이번 글에서는 4가지 Promsie 동시성 정적 메서드를 정리합니다.
우선 Promise 객체의 세 가지 상태
에 대해 얘기하려고합니다.
Promise 객체 상태는 아래 세 가지 중 하나를 가집니다.
fulfilled
(이행된): 작업이 성공했음을 의미합니다rejected
(거부된): 작업이 실패했음을 의미합니다pending
(보류): 이행된 상태도 아니고 거부된 상태도 아닌 상태입니다이행되었거나 거부되었다면settled
(결정)되었다고 합니다.
Promise의 초기값은 pending입니다. 아래 그림처럼 작업의 처리 결과에 따라 Promise는 이행된 상태 또는 거부된 상태가 됩니다. 새로운 Promise를 반환하여 chaning됩니다.
Promise 동시성 정적 메서드는 다음과 같은 특징을 가집니다.
const promise = Promise.all([promise1, promise2]);
인자로 받은 이터러블 Promise 중에서 가장 먼저 이행된 결과를 얻고 싶을 때 사용합니다.
Promise.any()는 입력 받은 하나의 Promise중 하나라도 이행될때, 가장 첫 번째로 이행된 Promise의 이행된 값을 가집니다.
다음 예제에서 입력 Promise 배열 중 가장 먼저 이행되는 promise2
의 값을 가집니다.
const promise1 = Promise.reject("promise1");
const promise2 = new Promise((resolve) => {
setTimeout(resolve, 100, "promise2")
});
const promise3 = new Promise((resolve) => {
setTimeout(resolve, 500, "promise3")
});
const promises = [promise1, promise2, promise3];
// 가장 먼저 이행된 promise2
Promise.any(promises).then((value) => console.log(value)); // "promsie2"
아래와 같이 모든 이터러블 Promise가 거부
되는 경우 Promise.any() 정적메서드의 반환 Promise도 거부됩니다.
거부될때 AggregateError 에러와 함께 거부된 이유(reason)을 담고있는 errors 프러퍼티 가집니다.
const promise1 = Promise.reject("promise1");
const promise2 = Promise.reject("promise2");
const promise3 = Promise.reject("promise3");
const promises = [promise1, promise2, promise3];
Promise.any(promises).catch((e) => {
console.log(e instanceof AggregateError); // true
console.log(e.errors); // [ 'promise1', 'promise2', 'promise3' ]
});
Promise.race()는 가장 먼저 Settled
(이행되었거나 거부)된 Promise의 값을 가지고 싶을 때 사용합니다.
아래 예제에서는 가장 먼저 settled된 promise1의 값을 가집니다. promise1은 거부되었기 때문에 Promise.race()의 반환 Promise의 거부된 값도 promise1을 가집니다
const promise1 = Promise.reject("promise1");
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, "promise2"));
const promise3 = new Promise((resolve) => setTimeout(resolve, 500, "promise3"));
const promises = [promise1, promise2, promise3];
Promise.race(promises)
.catch((e) => {
console.log(e); // "promise1"
// 가장 먼저 settled된 promise1
});
이러한 Promise.race()의 특성을 사용하면 비동기 작업의 타임아웃
기능을 구현할 수 있습니다.
function timeout(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('Timeout'));
}, ms);
});
}
function fetchData() {
return new Promise((resolve, reject) => {
});
}
Promise.race([fetchData(), timeout(5000)])
.then(result => {
// 완료된 작업처리
})
.catch(error => {
// 타임아웃
});
Promise.all() 정적메서드는 여러 개의 Promise가 모두 이행할 때까지 기다리고 모든 결과를 한꺼번에 얻고 싶을 때 사용합니다.
입력받은 모든
Promise가 이행되어야만 이행되는 Promise를 반환합니다. 만약 하나의 Promise라도 거부된다면 반환 Promise는 거부됩니다. 그외에도 아래와 같은 특징이 있습니다.
6초
가 지나야만 반환 Promise를 얻을 수 있습니다.배열
입니다.const promise1 = Promise.resolve("promise1");
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, "promise2"));
const promise3 = new Promise((resolve) => setTimeout(resolve, 500, "promise3"));
const promises = [promise1, promise2, promise3];
Promise.all(promises)
.then((value) => {
console.log(value); // [ 'promise1', 'promise2', 'promise3' ]
})
만약 단 하나의 Promise라도 거부된다면 Promise.all()의 반환메서드는 거부됩니다.
const promise1 = Promise.reject("promise1");
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, "promise2"));
const promise3 = new Promise((resolve) => setTimeout(resolve, 500, "promise3"));
const promises = [promise1, promise2, promise3];
Promise.all(promises)
.catch((e) => {
console.log(e); // promise1
});
Promise.allSettled() 정적메서드의 반환 Promise의 이행값도 Promise.all()과 같이 배열
입니다. 단, 메서드 이름에서 알 수 있듯 입력 Promise들이 이행되었을뿐만 아니라 거부되었을때
이행되는 반환 Promise를 가집니다.
반환값은 status
,reason
또는value
프러퍼티를 가지는 객체의 배열입니다.
const promise1 = Promise.reject("promise1");
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, "promise2"));
const promise3 = new Promise((resolve) => setTimeout(resolve, 500, "promise3"));
const promises = [promise1, promise2, promise3];
Promise.allSettled(promises).then((value) => {
console.log(value);
});
// [
// { status: 'rejected', reason: 'promise1' },
// { status: 'fulfilled', value: 'promise2' },
// { status: 'fulfilled', value: 'promise3' }
// ]
Promise.all()
Promise.any()
Promise.race()
Promise.allSettled()