자바스크립트 Promise.all() 이해하기 본문
반응형
Promise.all(iterable)
- 주로 배열을 인자로 받아서 인자로 받은 반복가능한 객체들을 순회하면서 비동기 작업들을 처리합니다.
- 입력 값으로 들어온 프로미스 중 하나라도 거부 당하면
Promise.all()
은 즉시 거부합니다. - 만약 비동기 작업이 아니라 의미없는 [1,2,3]와 같은 데이터를 인자로 넘겨주면 all메서드는 다음과 같은 작업을 자동으로 수행합니다.
Promise.all([Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)]);
- 이는 내부적으로
Promise.resolve()
메서드가 호출되어 인자로 전달된 값이 프로미스 객체로 변환되기 때문입니다. - 빈 객체를 전달한 경우, (동기적으로) 이미 이행한 프로미스를 반환합니다.
Promise.all([]).then(console.log) // []
- 콘솔에서 실행해주세요
var PromiseAllResult = Promise.all([
Promise.resolve('VALUE 01'),
Promise.resolve('VALUE 02'),
// Promise.reject('VALUE 02'),
Promise.resolve('VALUE 03'),
]);
setTimeout(function () {
console.log(`all메서드의 결과 : `, PromiseAllResult)
});
// all메서드의 결과 : Promise {<fulfilled>: Array(3)}
// all메서드의 결과 : Promise {<rejected>: 'VALUE 02'}
- 모두 reolve일 경우는 Promise(fullfilled)
- 하나라도 reject일 경우는 Promise(rejected)
Promise.all()의 동기성 / 비동기성
var p = Promise.all([]); // 즉시 이행함
var p2 = Promise.all([1337, "hi"]); // 프로미스가 아닌 값은 무시하지만 비동기적으로 실행됨
console.log(p);
console.log(p2);
setTimeout(function() {
console.log('the stack is now empty');
console.log(p2);
});
// 출력
// Promise { <state>: "fulfilled", <value>: Array[0] }
// Promise { <state>: "pending" }
// the stack is now empty
// Promise { <state>: "fulfilled", <value>: Array[2] }
- Promise.all()은 비동기적으로 동작하지만, 만약 인자가 빈객체라면 동기적으로 실행됩니다.
- 즉, 실행하자마자 바로 값을 반환해버립니다.
- 이것은 거부일때도 마찬가지입니다.
Promise.all()의 실패 우선성
Promise.all()
은 배열 내 요소 중 어느 하나라도 거부하면 즉시 거부합니다. 예를 들어, 일정 시간이 지난 이후 이행하는 네 개의 프로미스와, 즉시 거부하는 하나의 프로미스를 전달한다면Promise.all()
도 즉시 거부합니다.
var p1 = new Promise((resolve, reject) => {
setTimeout(() => resolve('하나'), 1000);
});
var p2 = new Promise((resolve, reject) => {
setTimeout(() => resolve('둘'), 2000);
});
var p3 = new Promise((resolve, reject) => {
setTimeout(() => resolve('셋'), 3000);
});
var p4 = new Promise((resolve, reject) => {
setTimeout(() => resolve('넷'), 4000);
});
var p5 = new Promise((resolve, reject) => {
reject(new Error('거부'));
});
// .catch 사용:
Promise.all([p1, p2, p3, p4, p5])
.then(values => {
console.log(values);
})
.catch(error => {
console.log(error.message)
});
// 콘솔 출력값:
// "거부"
Promise.all() 실패우선성 방지하기
var p1 = new Promise((resolve, reject) => {
setTimeout(() => resolve('p1_지연_이행'), 1000);
});
var p2 = new Promise((resolve, reject) => {
reject(new Error('p2_즉시_거부'));
});
Promise.all([
p1,
p2.catch(error => error.message),
]).then(values => {
console.log(values[0]) // "p1_지연_이행"
console.log(values[1]) // "p2_즉시_거부"
})
- p2는 즉시거부되므로 all 메서드를 태우게되면 당연히 Promise.all은 실패해서 catch 블록에서 에러핸들링을 해야합니다.
- 그러나 발생할 수 있는 거부를 사전에 처리해 동작 방식을 바꿀 수 있습니다.
- p2.catch(err ⇒ err.message)는 새로운 프라미스 객체를 반환하게 되고 return 값으로 err.message를 전달하고 있습니다.
- 따라서 p2에 catch (에러핸들링)을 붙임으로써 실패하지 않게되고 p1, p2.catch가 완료된 배열이 values에 최종적으로 들어가게 됩니다.
반응형
Promise.all() 예제코드
Promise.all([
new Promise((resolve) => setTimeout(() => {
console.log("01 실행")
resolve('VALUE 01')
}, 1000)),
new Promise((resolve) => setTimeout(() => {
console.log("02 실행")
resolve('VALUE 02')
}, 1500)),
// new Promise((_, reject) => setTimeout(() => reject('Error 01'), 1500)), // 실패
new Promise((resolve) => setTimeout(() => resolve('VALUE 03'), 2000)),
])
.then((results) => {
console.log('result of Promise.all() : ', results)
return results;
})
.catch((results) => {
console.log('in catch block : ', results)
return results;
})
.finally((results) =>
console.log('end of the Promise chain : ', results)
); // finally 콜백의 인자는 쓸모없는 인자입니다.
// 성공시
// 01 실행
// 02 실행
// result of Promise.all() : [ 'VALUE 01', 'VALUE 02', 'VALUE 03' ]
// end of the Promise chain : undefined
// 실패시
// 01 실행
// 02 실행
// in catch block : Error 01
// end of the Promise chain : undefinedd
반응형
'JavaScript' 카테고리의 다른 글
JS function vs arrow function (4) | 2023.05.31 |
---|---|
Javascript - this 키워드 (0) | 2023.05.30 |
자바스크립트 async / await 이해하기 (0) | 2023.05.24 |
자바스크립트 Promise.allSettled() 이해하기 (0) | 2023.04.25 |
자바스크립트 프라미스 (Promise) 이해하기 (0) | 2023.04.25 |
Comments