리액트와 그래프큐엘을 이용하여 프로젝트를 진행하면서 배열 내 요소들을 반복적으로 페칭을 할 때가 있다.
이 때, 조금 더 효율적인 방법을 고려하다가 Promise.all을 이용하여 반복적으로 페칭하는 방법을 사용해 봤다.
Promise.all() 메서드는 순회 가능한 객체에 주어진 모든 프로미스가 이행한 후, 혹은 프로미스가 주어지지 않았을 때 이행하는 Promise를 반환합니다. 주어진 프로미스 중 하나가 거부하는 경우, 첫 번째로 거절한 프로미스의 이유를 사용해 자신도 거부합니다.
-MDN-
Promise.all은 파라미터로 배열을 받는다. 따라서 모든 요소가 프로미스 객체이거나 프로미스 객체가 포함된 배열을 Promise.all()의 파라미터에 인자로 넣어준다.
이 때, Promise.all은 배열 안에 모든 요소가 성공적인지, 가장 먼저 실패한 요소가 있다면 실패한 요소의 실패 이유를 반환하게 된다.
const promiseResult = Promise.all([...]);
console.log(promiseResult); // Promise { <state>: "fulfilled", <value>: Array[...] }
먼저, 각 배열의 객체가 여러개 있다고 가정하고, 그 객체별로 id를 서버에 보내는 그래프큐엘 페칭을 한다고 생각해 보자.
예시 코드
const getData = async () => {
const initData = [];
const tempPromise = [];
myData.items.forEach((examData) => {
const promise = client
.query({ query: FETCH_TEST, variables: { id: examData._id } })
.then((res: any) => initData.push(res.data));
tempPromise.push(promise);
});
await Promise.all(tempPromise);
};
반복문을 이용하여 비동기 처리를 하고 Promise 객체를 Promise.all에 넣고 한번에 결과를 확인하는 경우와 하나씩 비동기처리를 하는 경우.. 어떤 방식이 효율적인가 고민했을 때, 전자를 사용하는 방식이 효율적이라고 생각되었다.
위와 같이 forEach와 Promise.all을 이용하여 한번에 비동기처리를 하면 반복문이 중간에 비동기처리의 결과를 기다릴 필요가 없어 성능상 유리할 것이라 생각된다.
실제로 얼마나 차이가 있을지는 성능 측정이 필요하기에 차후에 테스트를 해보고 기록해보도록 하겠다.