이때까지 하나의 Promise 객체를 다루기 위해 알아야 하기 위해 공부했다.
하지만 실무 개발에서는 여러 개의 Promise 객체를 다뤄야 할 일도 종종 발생하는데,
이번에는 여러 개의 Promise 객체를 다뤄보는 Promise.all 메소드에 대해 araboza.
Promise.all
다음과같이 id 638번부터 642번에 해당하는 데이터를 받아와서 출력하는 코드가 있다.
// main.js
async function printList(id) {
const response = await fetch(`https://todo-api.fesp.shop/api/todolist/${id}`)
const data = await response.json();
console.log(data);
}
for (let i = 638; i < 642 ; i++){
printList(i)
}
이번엔 데이터를 바로바로 출력하는 게 아니라
배열에 저장해 두었다가 모든 데이터가 저장되고 나서 배열을 출력해보자.
(함수 바깥에서 값을 받아오려면 await문을 사용해야 한다는 점을 참고)
// main.js
async function getList(id) {
const response = await fetch(`https://todo-api.fesp.shop/api/todolist/${id}`)
const data = await response.json();
return data; // data를 반환
}
for (let i = 638; i < 642 ; i++){
const List = await getList(i) // 함수 바깥에서 값을 받아오기 위해 await 사용
}
그런데 await을 사용하면 getList 함수가 완전히 끝날 때까지 기다린 후에
다음 줄로 넘어가기 때문에,
리퀘스트를 보내고 파싱하는 작업을 순차적으로 하게된다.
이럴 때 바로 Promise.all 메소드를 활용할 수 있으며
Promise.all은 여러 Promise를 동시에 기다릴 때 사용한다.
먼저 promise라는 배열을 만들고
// main.js
async function getList(id) {
const response = await fetch(`https://todo-api.fesp.shop/api/todolist/${id}`)
const data = await response.json();
return data; // data를 반환
}
const promise = []; // promise 배열 생성
for (let i = 638; i < 642 ; i++){
const List = await getList(i) // 함수 바깥에서 값을 받아오기 위해 await 사용
}
.
getList의 결과를 await하지 않고 바로 배열에 추가한다.
// main.js
async function getList(id) {
const response = await fetch(`https://todo-api.fesp.shop/api/todolist/${id}`)
const data = await response.json();
return data; // data를 반환
}
const promise = []; // promise 배열 생성
for (let i = 638; i < 642 ; i++){
promise.push(getList(i)) // promise 배열에 data를 넣어줌
}
이렇게 하면 await을 하지 않기 때문에
리퀘시트를 거의 병렬적으로 보내게 된다.
그리고 promise 배열에 추가되는 것은 Promise 객체라는 점도 기억해야한다.
마지막으로 promise.all 메소드를 작성한다.
// main.js
async function getList(id) {
const response = await fetch(`https://todo-api.fesp.shop/api/todolist/${id}`)
const data = await response.json();
return data; // data를 반환
}
const promise = []; // promise 배열 생성
for (let i = 638; i < 642 ; i++){
promise.push(getList(i)) // promise 배열에 data를 넣어줌
}
Promise.all(promise); // promise.all로 promise 배열을 실행
■ 해석 과정
promise는 Promise 배열이므로 풀어서 작성해보면 [p638, p639 ... p642]으로 볼 수 있는데
처음에는 배열에 있는 Promise들이 모두 Pending 상태일 것이다.
Promise.all 메소드도 Promise를 리턴하는데
처음에는 Pending 상태이다가
아규먼트로 전달된 Promise들이 모두 Fulfilled 상태가 되면
Promise도 Fulfilled 상태가 되고
각 Promise의 성공 결과값들로 이루어진 배열을 성공 결과값으로 갖게된다.
이 예시의 경우 todo데이터로 이루어진 배열이 성공 결과값이 되는 것이다.
반대로 아규먼트로 전달한 Promise 중
하나라도 Rejected 상태가 되면
Promise도 Rejected 상태가 되고
Rejected된 Promise의 오류를 결과값으로 갖게된다.
Promise.all도 결국 Promise 객체를 리턴하기 때문에
await이나 then 메소드를 이용할 수 있다.
한번 await으로 사용해보자.
// main.js
async function getList(id) {
const response = await fetch(`https://todo-api.fesp.shop/api/todolist/${id}`)
const data = await response.json();
return data; // data를 반환
}
const promise = []; // promise 배열 생성
for (let i = 638; i < 642 ; i++) {
promise.push(getList(i)) // promise 배열에 data를 넣어줌
}
const list = await Promise.all(promise); // await를 사용하여 promise.all로 promise 배열을 실행
console.log(list);
await을 이용해서 성공 결과값, 즉 todo 배열을 가져왔다.
실행해보면 데이터가 잘 출력되는 것을 확인할 수 있으며
또한 다음과 같이 try catch를 이용해서 오류 처리를 할 수도있다.
// main.js
async function getList(id) {
const response = await fetch(`https://todo-api.fesp.shop/api/todolist/${id}`)
const data = await response.json();
return data; // data를 반환
}
const promise = []; // promise 배열 생성
for (let i = 638; i < 642 ; i++) {
promise.push(getList(i)) // promise 배열에 data를 넣어줌
}
let list;
try {
list = await Promise.all(promise); // await를 사용하여 promise.all로 promise 배열을 실행
} catch (error) {
console.error(error);
}
console.log(list);
list 변수를 try문 바깥에서도 사용할 수 있도록 try 바깥에서 선언했다.
이렇게 Promise.all 부분에서 오류가 발생하더라도
try catch문으로 오류처리를 할 수 있다.
Promise를 활용하는 비동기 작업 여러 개를 병렬적으로 처리하고 싶을 때는
Promise.all 메소드를 사용하자.
'JS' 카테고리의 다른 글
(1) Sending a request with JavaScript (0) | 2025.01.28 |
---|---|
(5) ~ (13) Promise 정리 (0) | 2025.01.28 |
(12) Asynchronous JavaScript - catch(), finally() 메소드 (0) | 2025.01.23 |
(11) Asynchronous JavaScript - then() 메소드 (0) | 2025.01.10 |
(10) Asynchronous JavaScript - Promise와 오류 (0) | 2025.01.09 |