실무에서는 여러개의 promise 객체를 다뤄야할 일도 종종 발생한다. 

데이터를 바로 출력하지 않고 배열에 저장해두었다가 모든 데이터가 저장되고 나서 배열을 출력해보도록 하자.

async function getEmployee(id) {
  const response = await fetch('https://learn.codeit.kr/api/employees/${id}');
  const data =  await response.json();
  return data;
};

for (let i = 1; i < 11; i++) {
  const employee = await getEmployee(i); //함수 바깥에서 값을 받아오려면 await문을 써야한다.
}

(for문) 함수 바깥에서 값을 받아오려면 await 문을 써야한다. 하지만 await이 있으면 getEmployee 함수가 완전히 끝날 때까지 기다린 후에 다음줄로 넘어가기 때문에 리퀘스트를 보내고 파싱하는 작업을 순차적으로 하게된다. 이럴 때 promise.all 메소드를 활용할 수 있다. 

Promise.all은 여러 promise를 동시에 기다릴때 사용한다.

async function getEmployee(id) {
  const response = await fetch('https://learn.codeit.kr/api/employees/${id}');
  const data =  await response.json();
  return data;
};
//promises 배열에 추가되는 것은 promise 객체이다.
const promises = []; //일단 이렇게 promises라는 배열을 만들고

for (let i = 1; i < 11; i++) {
  promises.push(getEmployee(i)); //getEmployee의 결과를 await하지않고 바로 배열에 추가
}

이렇게 하면 await을 하지 않기 때문에 리퀘스트를 거의 병렬적으로 보내게된다. (promises 배열에 추가되는 것은 promise 객체이다.)

async function getEmployee(id) {
  const response = await fetch('https://learn.codeit.kr/api/employees/${id}');
  const data =  await response.json();
  return data;
};

const promises = []; 

for (let i = 1; i < 11; i++) {
  promises.push(getEmployee(i));
}

Promise.all(promises); //추가

Promise.all(promises); 를 풀어서 작성해보자면 이렇게 된다.

Promise.all([p1,     p2,     p3,     p4,     p5,     ...]);

처음에는 배열에 있는 promise들이 모두 pending 상태일 것이다.

pending 상태

Promise.all 메소드도 promise를 리턴하는데 처음에는 pending 상태이다가 아규먼트로 전달된 promise들이 모두 fulfilled 상태가 되면 Promise.all도 fulfilled 상태가 되고, 

각 promise의 성공 결과값들로 이루어진 배열을 성공 결과값으로 갖게된다. 지금 쓰고 있는 예시의 경우 직원 데이터로 이루어진 배열이 성공 결과값이 될것이다.

반대로 아규먼트로 전달한 promise 중 하나라도 rejected 상태가 되면 Promise.all도 rejected 상태가 되고 rejected된 promise의 오류를 결과값으로 갖게된다.


Promise.all도 결국 promise 객체를 리턴하기 때문에 await이나 then 메소드를 이용할 수 있다.

async function getEmployee(id) {
  const response = await fetch('https://learn.codeit.kr/api/employees/${id}');
  const data =  await response.json();
  return data;
};

const promises = []; 

for (let i = 1; i < 11; i++) {
  promises.push(getEmployee(i));
}

const employees = await Promise.all(promises); //await 이용
console.log(employees);

await을 이용해서 성공 결과값, 즉 직원 배열을 가져왔다. 위 코드를 실행해보면 직원 코드가 잘 출력된다.


Promise.all도 try catch문을 이용해서 오류를 처리할 수도 있다.

async function getEmployee(id) {
  const response = await fetch(`https://learn.codeit.kr/api/employees/${id}`);
  const data = await response.json();
  return data;
}

const promises = [];

for (let i = 1; i < 11; i++) {
  promises.push(getEmployee(i));
}

let employees; //try문 바깥에서 선언

try {
  employees = await Promise.all(promises);
} catch (error) {
  console.log(error);
}

console.log(employees);

getEmployee 변수를 try문 바깥에서도 사용할 수 있도록 try문 바깥에서 선언했다. 그러면 Promise.all 부분에서 오류가 나도 try catch문이 오류를 잡아준다.

promise를 활용하는 비동기 작업 여러개를 병렬적으로 처리하고 싶을 땐 Promise.all 메소드를 사용하면 된다. (여러 비동기 작업을 한꺼번에 처리)

+ Recent posts