비동기 함수를 병렬적으로 실행하는 법

만약 여러 개의 비동기 함수를 실행 시켜야한다면 어떻게 해야 될까요. 모든 비동기 함수에 await를 붙여 하나씩 실행시키는 것보다는 먼저 모든 함수를 실행시켜놓고 모든 작업이 완료되길 기다리는 것이 더욱 효율적이겠죠? 자바스크립트에서는 Promise.allSettled를 사용하여 이런 방식이 가능합니다.

const results = await Promise.allSettled([promise1, promise2, promise3, ...]);

results.forEach((result, index) => {
    // 비동기 함수 실행 성공
    if (result.status === 'fulfilled') {
      console.log(`Promise ${index + 1} fulfilled with result`);
      console.log(result.value);
    } else {
    // 비동기 함수 실행 실패
      console.error(`Promise ${index + 1} rejected with error`);
      console.log(result.reason);
    }
  });
}

allSettled로 반환된 Promise들은 status의 값으로 fulfilled와 rejected를 가져 성공과 실패 여부를 알 수 있습니다. 그리고 완료된 값들은 각각의 결과로 반환된 값에서 value를 키로 사용하여 접근할 수 있습니다. 만약 실패하였다면 reason을 통해 실패되어 반환된 값에 접근할 수 있습니다

all을 사용하여 같은 효과를 얻을 수 있지만 allSettled와는 달리 어떤 Promise가 실패했는 지 알 수가 없어 allsettled 사용을 추천합니다.

axios 인스턴스 만들기

HTTP 요청을 보내는 라이브러리인 axios는 여러가지 편의기능이 있습니다. 그 중 가장 널리 쓰일만한 옵션을 소개하겠습니다. 소개 된 옵션외에도 headers를 통해 요청 헤더를 추가할 수도 있습니다.

import axios from "axios";

const API = axios.create({
  baseURL: "https://example.com",
  withCredentials: true,
});

export default axiosInstance;

위와 같이 aixos.create를 이용한다면 요청을 보낼 때 공통으로 사용하는 주소나 헤더를 중복하여 작성할 필요가 없습니다.
baseURL: 요청을 보낼 기본 주소를 설정할 수 있습니다. 만약 baseURL이 https://example.com이라면 해당 인스턴스로 보내는 모든 요청은 https://example.com로 시작하는 주소가 됩니다.
withCredentaials: 다른 도메인에 보내는 요청에 인증과 관련된 정보(쿠키)를 담을 수 있게 해주는 옵션입니다. 서버에서도 Access-Control-Allow-Credentials 헤더를 true로 설정하였다면 클라이언트와 서버가 서로 다른 도메인이더라도(혹은 포트번호가 다르더라도) credentaial을 포함한 요청을 보낼 수 있게 됩니다.

 

위의 코드에서 export한 axiosInstance를 요청을 보내는 곳에서 다음과 같이 사용하면 됩니다.

import

axiosInstance.get("something", {headers: {Authorization: token}})
// https://example.com/something으로 요청이 보내진다.

 

추가적으로 다음과 같이 production 환경과 development환경을 구분하여 baseURL을 설정할 수도 있습니다.

const isProduction = env.(환경변수이름) === "production";
const URL = isProduction ? "https://배포된 백엔드 주소" : "http://localhost";

객체 안의 빈 문자열 등 false로 평가되는 값을 가진 키는 요청에서 제외시키기

사용자가 입력한 값을 이용해 HTTP 요청을 보낼 때, 특히 PUT으로 수정요청을 보낼 때, 사용자가 입력하지 않은 값들을 보낼 경우 대부분 빈 문자열이 들어가게 됩니다. 대부분의 경우 문제는 없지만 백엔드에서 빈 문자열을 따로 처리하지 않고 그대로 사용할 경우에 예상치 못한 동작이 일어날 수 있습니다. 백엔드에서 처리를 하면 굳이 필요하지는 않지만 요청을 보내는 데이터를 조금 더 줄일 수 있고 백엔드에서 미처 처리하지 못한 경우를 대비해 false로 평가되는 값을 가진 객체의 키들은 요청에서 제외시키는 코드를 추가해 보겠습니다.

const filteredData = Object.fromEntries(  
  Object.entries(data).filter(([key, value]) => value)  
);

Object.fromEntries(): 키-값 배열을 인수로 받아 객체로 만드는 역할을 합니다.
Object.entries(data): 객체의 키-값을 [key, value]를 요소로 가진 배열로 만들어줍니다.
filter(([key, value]) => value): value가 true로 평가될 경우를 찾아 배열로 만들어줍니다.

 

위의 간단한 코드를 통해 값이 존재하는 키들만 요청에 포함시킬 수 있습니다.

+ Recent posts