[Javascript] 2개 이상의 Promise 함수들을 비동기 호출하기

BinaryWoo_dev·2023년 5월 6일
0

javascript

목록 보기
3/8

🔎 서론


갈수록 복잡한 애플리케이션들이 다양해지는 요즘, API 호출 횟수를 아무리 줄인다 하더라도 어쩔 수 없이 2개 이상의 API를 호출해야하는 경우가 빈번하다. 이럴 때, await 키워드로 API 각각을 따로 호출하기 보다는 Axios.all() 또는 Promise.all() 을 이용해보는 것은 어떨까?

🎯 본론


만약 SSR 을 통해 messages, users 라는 데이터를 return 해주는 API 2개를 호출하는 로직을 기본적인 방법으로 구현하려면 아래와 같다.

기본 방법

export const getServerSideProps = async () => {
	const { messages } = await fetcher(GET_MESSAGES);
	const { users } = await fetcher(GET_USERS); // 위의 fetcher(GET_MESSAGES) 호출이 완전히 완료되어야 호출됨.

	return {
		props: {
			serverSideMessages: messages ?? [],
			users: users ?? []
		}
	};
};

이렇게 작성해도 기능상으로는 잘 작동하지만, API return data가 큰 경우에는 성능상의 문제가 발생할 수도 있다. 위의 코드의 문제점은 아래와 같다.

await fetcher API 호출 함수가 순차적으로(동기적으로) 호출됨.

이 말은 즉, 위의 코드를 기준으로 봤을 떄 messages 데이터를 불러오는 fetcher(GET_MESSAGES) API 함수가 가장 먼저 호출되며 resolve() 또는 fulfilled 를 반환하기 전까지는 fetcher(GET_USERS) API 함수는 호출되지 않는다는 의미이다. 이렇게 되면 모든 데이터가 완전히 로드되기 까지의 소요 시간이 불필요하게 길어질 수 있다.
따라서, 이런 경우 아래의 방법들로 해당 이슈를 개선할 수 있다.

Promise.all(Awaited[ ])

  • Promise 객체에 await 키워드를 붙인다.
  • Promise 타입을 반환하는 API 호출 함수들에 대한 Array를 .all() 메서드의 인자에 삽입한다.
  • Array 에 들어있는 API 호출 함수 index 기준으로 return data를 받을 수 있으며, 아래의 코드에서는 es6의 구조분해할당 문법으로 messages, users 를 바로 정의하였다.
export const getServerSideProps = async () => {
  const [{ messages }, { users }] = await Promise.all([
		fetcher(GET_MESSAGES),
		fetcher(GET_USERS)
	]);
  return {
    props: {
      serverSideMessages: messages ?? [],
      users: users ?? []
    }
  };
};

axios.all(Awaited[ ])

    • Promise 타입을 반환하는 API 호출 함수들에 대한 Array를 .all() 메서드의 인자에 삽입한다.
  • .all() 메서드에 .then(axios.apread(res1, res2, ...) => {...}) 함수 내부에서 Array 에 들어있는 API 호출 함수 index 기준으로 return data를 핸들링 할 수 있다.
    또한, 아래의 코드 형식처럼 spread() 파라미터를 생략하여 es6의 객체 구조 분해 할당 문법을 사용할 수도 있다.
import axios from 'Axios';

export const getServerSideProps = async () => {
  const { messages, users } = axios.all([fetcher(GET_MESSAGES), fetcher(GET_USERS)]).then(axios.spread());

  return {
    props: {
      serverSideMessages: messages ?? [],
      users: users ?? []
    }
  };
}

💡결론


  • API 호출 로직만 잘 개선해도 프론트엔드 성능 향상에 아주 큰 기여를 할 수 있을 것 같다.
  • 하지만 비동기는 여전히 어려운 개념 중 하나인 것 같다.
profile
매일 0.1%씩 성장하는 Junior Web Front-end Developer 💻🔥

0개의 댓글