์ํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์ redux ๋ฐ DB์ ์ ์ฅํ๋ค.
๋ฐ์ดํฐ ์ ๊ณต์ ์คํ API๋ฅผ ์ฌ์ฉํจ.
์ํ ์งํฅ ์์ํ : https://www.kobis.or.kr/kobisopenapi/homepg/apiservice/searchServiceInfo.do?serviceId=searchDailyBoxOffice
๋ฐ์ดํฐ ๊ฐ์ ธ์ค๋๊ฑด ๊ธ๋ฐฉ ํ์ง!
์์ ๋ง๋งํ๊ฒ ์์ํ๋๋ฐ ์์๋ชปํ ๋๊ด์ด ์๊ฒผ๋ค. ๋ด๊ฐ ํ์ํ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ API๊ฐ ์๋ค๋ ๊ฒโฆ OMG
๋๋ ์ํ ์ค๊ฑฐ๋ฆฌ์ ํฌ์คํฐ๊ฐ ํฌํจ๋ ๋ฐ์ดํฐ๊ฐ ํ์ํ๋ฐ ๊ณต๊ณต๋ฐ์ดํฐํฌํธ์ด๋ ๋ค์ด๋ฒ์์๋ ํด๋น ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ API๊ฐ ์์๋ค. ์ด์ ์ ํด์ธ ์ํ API๋ฅผ ์ฌ์ฉํ์ ๋๋ ์ํ ์ ๋ชฉ, ์ค๊ฑฐ๋ฆฌ, ์ธ๋ค์ผ ๋ฑ ๋ค์ํ ์ ๋ณด๊ฐ ๋ชจ๋ ์ ๊ณต๋์ด์ ๋น์ฐํ ๊ตญ๋ด API๋ ๋น์ทํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง ์ค ์์์ด์ ๋ฉ๋ถ์ด์๋ค.
ํ๊ตญ ๊ธฐ์ค์ ์ํ ๋ฆฌ์คํธ๋ฅผ ์ฌ์ฉํ๊ณ ์ถ์ด์ ๊ผญ ๊ตญ๋ด API๊ฐ ํ์ํ๋๋ฐ ํฌ๊ธฐํด์ผํ๋ ์ถ์ ์ฐฐ๋ KMDb
์์ ์ ๊ณตํ๋ API๋ฅผ ๋ฐ๊ฒฌํ๋ค. ์ฌ๊ธด ์๋ ์ฌ๋๋ ์ ์๋๊ฑฐ ๊ฐ๊ณ ์๋ฃ๋ ๋ง์ด ์์ด์ ํ์ฉ๋ฐฉ๋ฒ์ ๋ณ๋์ ๊ฒ์๊ธ๋ก ๋ง๋๋ ค๊ณ ํ๋ค.
์ฃผ์ํ ์ ์ API ์ค๋ช ๋ฌธ์์ ์์ฒญ์ธ์๊ณผ ์ถ๋ ฅ๊ฐ ๋ณ์๋ช ์ด ์ข ๋ค๋ฅธ ๊ฒฝ์ฐ๊ฐ ์๋ค. poster๊ฐ์ ๊ฒฝ์ฐ๋ ๋ฌธ์์๋ posterURL์ด๋ผ๊ณ ๋์ด์๋๋ฐ ์ค์ ๋ก๋ posters์. ํ์ํ ๋ฐ์ดํฐ๋ ๋ฌธ์์ ๋ณ์๋ช ๊ณผ ์ค์ ๋ฐ์ดํฐ๋ฅผ ๊ผญ ํ์ธํ์!
KMDb์์ ์ ๊ณตํ๋ ๋ฐ์ดํฐ๋ ๊ทธ๋ฅ ์ํ ์ ๋ณด๊ฐ ์ ๋ถ์ด๋ค. ์ด๋ ๊ฒ API์๊ธ๋์ ๋น ์ง์ค์ ์์๋ ๋ชปํ๊ณ ์ด๋ฏธ ๋ฉ์ธํ๋ฉด์์ ์ธ๊ธฐ ์ํ๋ค ์ดค๋ฅด๋ฅต ๋ฉ์๊ฒ ๋จ๋๊ฑฐ ๋ค ๊ตฌ์ํด๋จ๋๋ฐ ํํ,,
์๋ฌด๋ฆฌ ์๊ฐํด๋ ๋ฐ์ค์คํผ์ค๋ฅผ ํฌ๊ธฐํ ์๊ฐ ์์ด์ ๋จธ๋ฆฌ๋ฅผ ๊ตด๋ ค๋ดฃ๋ค.
๋ฐ์ค์คํผ์ค API๋ ์ํ ์งํฅ ์์ํ์์ ์ ๊ณตํ๋๋ฐ ๊ฑฐ๊ธด ์ค๊ฑฐ๋ฆฌ๋ ํฌ์คํฐ ์ ๋ณด๊ฐ ์๊ณ ... KMDb๋ ์ง์ง ์ํ์ ๋ณด๋ง ์๊ณ ... ํ ...
๋๊ฐ ์์ด์ฐ๋ฉด ๋๊ฒ ๋ค!
๋ฐฉ๋ฒ์ ์ ์ธํํ๋ค.
1. ์ผ๋ณ ๋ฐ์ค์คํผ์ค ๋ฐ์ดํฐ๋ฅผ ๋จผ์ ๋ฐ์์์
2. ์๋ต๋ฐ์ดํฐ ์ค KMDb์์ฒญ์ธ์๋ก ์จ๋จน์ ์ ์์๋งํ๊ฑธ ๋ฝ์๋ด๊ณ
3. ๋ฝ์๋ธ ๋ฐ์ดํฐ๋ฅผ KMDb ์์ฒญ์ธ์๋ก ๋ฃ์ด์ ์ํ ์ ๋ณด๋ฅผ ๊ฒ์ํ๋ค.
KMDb์์ ๋ฐ์ค์คํผ์ค์ ์๋ ์ํ์ ์ ํํ ์ผ์นํ๋ ๋ฐ์ดํฐ๋ฅผ ๊บผ๋ด์์ผ ํ๋ฏ๋ก ์์ฒญ ์ธ์๋ฅผ ์ ์จ๋จน๋๊ฒ ์ ์ผ ์ค์ํ๋ค. ๋ API์ ๊ณตํต๋ ์ํ ์ฝ๋๊ฐ ์์ผ๋ฉด ์ข์๊ฒ ์ง๋ง ๊ทธ๋ฐ๊ฑด ์์์ใ ใ ๋๋ ์ ๋ชฉ, ๊ฐ๋ด์ผ, ์ ์์ฐ๋ ์ธ๊ฐ์ง ์๋ต ๋ฐ์ดํฐ๋ฅผ ์์ฒญ ์ธ์๋ก ์ฌ์ฉํ๋ค.
2๋ฒ์ฒ๋ผ ๋ API๋ฅผ ์์ด์ฐ๋ฉด ๋ด๊ฐ ์ํ๋ ๋ฐ์ดํฐ๋ ๊ฐ์ ธ์ฌ ์ ์์ง๋ง ํธ์ถ ํ์ ๊ฑฑ์ ์ ์ํ ์๊ฐ ์์๋ค.
KMDb์ ํธ์ถ ์ ํ ํ์๋ ์ผ์ผ 1000ํ์ธ๋ฐ
๋ฐ์ค์คํผ์ค ๋ชฉ๋ก์ ๋ค๊ณ ์ฌ๋ ํ๋ฒ์ 10๋ฒ์ฉ ํธ์ถํ๋๊น.. ํ์ด์ง ๋ฐฑ๋ฒ๋ง ์๋ก๊ณ ์นจํ๋ฉด ๋... ์ด๋ ๊ฒ ๋ณด๋ฉด ์ ๋ ๋ง์ ํ์๊ฐ ์๋๋ค.
์ด๋ป๊ฒํ๋ฉด ํธ์ถ์ ๋ ํ ์์์์ง ๊ณ ๋ฏผํ๋ค๊ฐ db๋ฅผ ํ์ฉํด๋ณด๊ธฐ๋ก ํ๋ค.
์ํ ๋ชฉ๋ก์ ๊ฐ์ ธ์ฌ ๋ ๋จผ์ db์ ๋ฐ์ดํฐ๊ฐ ์๋์ง ํ์ธํ๊ณ , ์๋ค๋ฉด api๋ฅผ ํธ์ถํด์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ , ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ฅผ db์๋ ์ ์ฅํ๋ค. ์ด๋ ๊ฒํ๋ฉด ์ต์ด๋ก ๊ฒ์ํ๋ ์ํ๊ฐ ์๋ ์ด์ db์๋ง ์ ๊ทผํ๊ฒ ๋๋ฏ๋ก API ํธ์ถ ํ์๋ฅผ ๋ง์ด ์ค์ผ ์ ์๋ค.
๋ค๋ง ์ต์ด ๊ฒ์์์๋ db์ ๊ทผ๊ณผ apiํธ์ถ์ด ์์ฐจ์ ์ผ๋ก ์งํ๋๋ฏ๋ก ์๋๊ฐ ๋๋ ค์ง ์ ์๋ค.
API๋ก ๋ฐ์ดํฐ๋ฅผ ๋ฝ์๋ผ ๋ ํ์ฌ์ผ์ ๊ธฐ์ค์ผ๋ก ์ต์ ๊ฐ๋ดํ ์ํ ๋ฐ์ดํฐ๋ฅผ ์ ๋นํ ๊ฐฏ์๋งํผ ๊ฐ์ ธ์์ผํ๋ค.
์ฒ์์๋ ๊ธฐ๊ฐ ๊ฒ์์ฉ API ์ธ์ ์ค ๊ฐ๋ด์ผ ์์์ ์๋ฏธํ๋ releaseDts
์ ์ค๋ ์ผ์๋ฅผ ์ฃผ๊ณ , listCount
๋ฅผ 15๊ฐ๋ก ์ค์ ํ๋ ๋ฐฉ์์ผ๋ก ์ฌ์ฉํ๋ค. ๋ฐ์ดํฐ๊ฐ ๊ฝค ๋ง์ด ๋ฝ์์ ธ์ ํ๋ฃจ์ ์ด๋ ๊ฒ ๋ง์ ์ํ๋ค์ด ๊ฐ๋ดํ๋๊ตฌ๋! ํ๊ณ ๋์ด๊ฐ ๋ป ํ๋๋ฐ ์๊ณ ๋ณด๋ ๊ฐ๋ด์ผ์ด YYYYMMDD ํฌ๋งท์ด ์๋๋ผ YYYY ๋๋ YYYYMM์ธ ๋ฐ์ดํฐ๊น์ง ๊ฒ์๋์๋ ๊ฒ์ด์๋ค. ์ด๊ฑด ์์ง ๊ฐ๋ด๋์ง ์์ ๊ฐ๋ด ์์ ์๋ค์ ์๋ฏธํ๋๊ฑฐ๋ผ ๋์๊ฒ ์ธ๋ชจ ์๋ ๋ฐ์ดํฐ๋ผ ๊ฒ์ ๋ฐฉ๋ฒ์ ๋ฐ๊ฟ์ผํ๋ค.
๋๋ฒ์งธ๋ก ์๊ฐํ ๋ฐฉ๋ฒ์ ๊ธฐ๊ฐ ๊ฒ์ ์ธ์ ์ค ๊ฐ๋ด์ผ ์ข
๋ฃ ์ธ์์ธreleaseDte
๋ง ๋จ๋
์ผ๋ก ์ฌ์ฉํ๋ ๊ฑฐ์๋ค. ๊ฐ๋ด์ผ ์ข
๋ฃ ์ธ์๋ฅผ ์ค๋๋ก ์ค์ ํ๊ณ ์ต์ ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ 15๊ฐ์ ๋ ๋ฝ์๋ด๋ฉด ์ฝ๊ฒ ํด๊ฒฐ๋ ๊ฒ ๊ฐ์๋ค.
ํ์ง๋ง ๋น์ฐํ๊ฒ๋ ์ฝ๊ฒ ํด๊ฒฐ ๋์ง ์์์ ใ
์ ๋ ฌ ์ธ์ ์ค '์ต์ ๊ฐ๋ด์'์ ๋ ฌ ๋ฐฉ๋ฒ์ด ์์๋คใ
ใ
๊ฒฐ๊ตญ ๊ทธ๋ฅ ๊ฐ๋ด ์์์ผ์ธ releaseDts
์ releaseDte
๋ฅผ ํจ๊ป ์ฌ์ฉํ๋ listCount
๋ฅผ 50๊ฐ์ ๋ ๋ฝ์์ ๊ฐ์ ธ์ค๋ ๋ฐฉ๋ฒ์ผ๋ก ์งํํ๋ค. 50๊ฐ์ ๋๋ฅผ ๋ฝ์ ์ด์ ๋ ์ฒซ๋ฒ์งธ ๋ฐฉ๋ฒ์์ ๋งํ ๊ฒ์ฒ๋ผ ๋น์ ์ ๋ ์ง ํฌ๋งท๊น์ง ํจ๊ป ๊ฒ์๋์ด๋ฒ๋ ค์ ๊ทธ ๋ฐ์ดํฐ๋ค์ ๊ฑธ๋ฌ์ผํ๊ธฐ ๋๋ฌธ์ด๋ค. ๋ถํ์ํ ๋ฐ์ดํฐ๋ค์ด ์๊ทผ ๋ง์์ 50๊ฐ์ ๋๋ ๊ฐ์ ธ์์ผ์ง 15~20๊ฐ ์ ๋์ ๋ฆฌ์คํธ๊ฐ ๋จ๋๋ผ.
๊ทธ๋ฆฌ๊ณ ์ต์ ์ํฉ ๋ฐ์ดํฐ๋ ๋ฐ์ค์คํผ์ค ๋ฐ์ดํฐ์ ๋ง์ฐฌ๊ฐ์ง๋ก db์ ์ ์ฅํด์ฃผ์๋ค. ์ด๊ฑด ๋ฐ์ค์คํผ์ค ๋ฐ์ดํฐ์ฒ๋ผ ํธ์ถ ํ์๋ฅผ ์ค์ด๋ ค๊ณ ํ๊ฑด ์๋๊ณ , ์ํ ๋ฐ์ดํฐ๋ฅผ ์ฐจ๊ทผ์ฐจ๊ทผ ๋ชจ์๋๋ฉด ์ถํ์ ์ธ ์ผ์ด ์์ ๊ฒ ๊ฐ์์๋ค.
๐ฆsrc
โฃ ๐api
โ โ ๐firebase.jsx
โฃ ๐components
โ โฃ ๐MovieCard.jsx
โ โฃ ๐MovieDetailModal.jsx
โฃ ๐pages
โ โฃ ๐Home.jsx
โ โฃ ๐Movies.jsx
โฃ ๐store
โ โฃ ๐movie-fetch.jsx
โ โ ๐movie-store.jsx
โฃ ๐util
โ โฃ ๐data.jsx
โ โ ๐date.jsx
โ ๐setupProxy.js
path='/' element=<Home/>
// db๋ก๋ถํฐ ๋ฐ์ดํฐ ์ฐพ๊ธฐ
export const searchMovies = async ({ title, releaseDate, movieCode }) => {
const snapshot = await get(child(dbRef, "/movies"));
if (snapshot.exists() && snapshot.val() !== null) {
const values = Object.values(snapshot.val());
return values.find((movie) => {
if (movie.title === title && movie.releaseDate === releaseDate) {
return movie;
} else if (movie.title === title && movie.movieCode === movieCode) {
return movie;
} else {
return null;
}
});
} else {
return null;
}
};
// ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ
export const addMovie = async (movie) => {
try {
await set(ref(db, `/movies/${movie.id}`), movie);
} catch (error) {
return;
}
};
const { configureStore, createSlice } = require("@reduxjs/toolkit");
const moviesSlice = createSlice({
name: "movies",
initialState: { boxOffice: [], recent: [], myMovies: [] },
reducers: {
getRecentMovies: (state, action) => {
state.recent = action.payload;
},
getBoxOfficeMovies: (state, action) => {
state.boxOffice = action.payload;
},
},
});
export const store = configureStore({
reducer: { movies: moviesSlice.reducer },
});
export const moviesAction = moviesSlice.actions;
import axios from "axios";
import { addMovie, searchMovies } from "../api/firebase";
import { dataFormat } from "../util/data";
import { getTodayDate } from "../util/date";
import { moviesAction } from "./movie-store";
/** api ์ฌ์ฉ */
const moviesClient = axios.create({
baseURL: "/search_json2.jsp",
params: {
collection: "kmdb_new2",
ServiceKey: process.env.REACT_APP_MOVIES_SERVICE_KEY,
detail: "Y",
},
});
const boxOfficeClient = axios.create({
baseURL: "/searchDailyBoxOfficeList.json",
params: {
key: process.env.REACT_APP_BOX_OFFICE_KEY,
targetDt: getTodayDate(),
},
});
// ๋ฆฌ๋์ค์ ๋ฐ์ค์คํผ์ค ๋ฐ์ดํฐ ์ ์ฅ
export const getBoxOfficeMoviesFetch = () => {
return async (dispatch) => {
// ๋ฐ์ค์คํผ์ค ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๊ณ
const boxOfficeData = await getBoxOffice();
if (boxOfficeData) {
// ๋ฐ์ดํฐ๊ฐ ์์ผ๋ฉด ํด๋น ์ํ ์ ๋ณด๋ฅผ ๊ฒ์ํ๋ค (์์ผ๋ฉด db์ ์ ์ฅํจ)
const moviesList = await getBoxOfficeMovies(boxOfficeData);
// ์ฐพ์ ์ํ ์ ๋ณด๋ฅผ ๋ฆฌ๋์ค์ ์
๋ฐ์ดํธํ๋ค
dispatch(moviesAction.getBoxOfficeMovies(moviesList));
}
};
};
// ๋ฆฌ๋์ค์ ์ต์ ์ํ ๋ฐ์ดํฐ ์ ์ฅ
export const getRecentMoviesFetch = () => {
let movieList = []; //๋ฆฌ๋์ค์ ์
๋ฐ์ดํธ ๋ ๋ฆฌ์คํธ
return async (dispatch) => {
const response = await moviesClient.get("", {
params: {
listCount: 50,
releaseDts: getPeriodDate(14), // ์ค๋๋ก๋ถํฐ 14์ผ ์ด์ ๋ ์ง
releaseDte: getPeriodDate(), // ์ค๋๋ ์ง
},
});
// db์ ํด๋น ๋ฐ์ดํฐ ์๋์ง ํ์ธํ๊ณ ๋ง์ฝ ๋ฐ์ดํฐ๊ฐ ์์ผ๋ฉด db์ ์ ์ฅ
const responseData = getResponseMovieData(response);
if (responseData) {
const responseData = getResponseMovieData(response);
for (const data of responseData) {
const formattedData = changeDataFormat(data);
// releaseDateํฌ๋งท์ด ๋น์ ์์ธ ๋ฐ์ดํฐ๋ฅผ ๊ฑฐ๋ฅธ๋ค
if (
formattedData.releaseDate.length !== 8 ||
formattedData.releaseDate.substring(6, 8) === "00"
) {
continue;
}
movieList.push(formattedData);
addMovie(formattedData);
}
}
dispatch(moviesAction.getRecentMovies(movieList));
};
};
// ๋ฐ์ค ์คํผ์ค ๋ฐ์ดํฐ๋ฅผ ๋ค๊ณ ์ด
const getBoxOffice = async () => {
const response = await boxOfficeClient.get("");
const responseData = response.data.boxOfficeResult.dailyBoxOfficeList;
return await responseData.map((data) => ({
movieCode: data.movieCd,
title: data.movieNm,
releaseDate: data.openDt.replace(/-/g, ""),
}));
};
// ๋ฐ์ค์คํผ์ค ์ํ ์ ๋ณด ๊ฒ์
export const getBoxOfficeMovies = async (boxOfficeData) => {
let movieList = []; //๋ฐํ๋ ์ํ ๋ฐ์ดํฐ, redux state๊ฐ ๋ ๊ฑฐ์
for await (const data of boxOfficeData) {
// db์ ํด๋น ์ํ๊ฐ ์๋์ง ๊ฒ์
const movie = await searchMovie(data);
// db์ ์์ผ๋ฉด moviesClient api๋ก ๋ฐ์ดํฐ ํจ์นญ
if (!movie) {
const response = await moviesClient.get("", {
params: {
title: data.title,
releaseDts: data.releaseDate,
},
});
const responseData = getResponseMovieData(response);
// ์๋ต ๋ฐ์ดํฐ๊ฐ ์์ผ๋ฉด db์ ์ ์ฅํ๊ณ movieList์ ์ถ๊ฐ
if (responseData && responseData.length > 0) {
for (const data of responseData) {
const formattedData = changeDataFormat(data);
addMovie(formattedData);
movieList.push(formattedData);
}
}
} else { // db์ ์์ผ๋ฉด movieList์ ์ถ๊ฐ
movieList.push(movie);
}
}
return movieList;
};
// api response์์ ์ํ ์ ๋ณด ์ถ์ถ
const getResponseMovieData = (response) => {
return response.data.Data[0].Result;
};
KMDb๋ ํน์ ์ํ๋ฅผ ์ง์ ํด์ ๊ฒ์ํ๋ฉด ์ ๋ชฉ์ !HS !HE ์ด๋ฐ๊ฒ ํฌํจ๋ผ์ ๋์ด. ์ ๊ทํํ์์ ์ด์ฉํด์ db์ ์ ์ฅํ ๋๋ ๋ถํ์ํ ๊ธ์๋ ๊ณต๋ฐฑ์ ์ ๊ฑฐํด์ค๋ค.
/** db์ ์ ์ฅํ ๋ฐ์ดํฐ๋ง ์ถ์ถํ๋ ๋ฉ์๋ */
export const dataFormat = (data) => {
const {
movieSeq,
Codes: {
Code: [{ CodeNo }],
},
title,
genre,
repRlsDate,
prodYear,
posters,
plots: {
plot: [{ plotText }],
},
runtime,
rating,
nation,
titleEng,
titleOrg,
directors: {
director: [{ directorNm }],
},
actors: { actor },
} = data;
/**์ ๊ทํํ์์ผ๋ก ์ ๋ชฉ ์์ */
let titleForamt = title
.replace(/!HS/g, "")
.replace(/!HE/g, "")
.replace(/^\s+|\s+$/g, "")
.replace(/ +/g, " ");
return {
id: movieSeq,
movieCode: CodeNo,
genre,
title: titleForamt,
releaseDate: repRlsDate,
prodYear,
poster: posters.split("|")[0],
summary: plotText,
runtime,
rating,
nation,
titleEng,
titleOrg,
director: directorNm,
actors: actor.map((it) => it.actorNm),
};
};
/** ๋ ์ง ์ ๋ณด YYYYMMDD */
export const getPeriodDate = (period = 0) => {
//์ค๋ ๋ ์ง๋ฅผ ๊ธฐ์ค์ผ๋ก, -period ๊ธฐ๊ฐ์ ๋ ์ง๋ฅผ ๋ฐํ
const today = new Date();
const dayAgo = new Date(today.setDate(today.getDate() - period));
const date = new Date(dayAgo);
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
return `${year}${month < 10 ? `0${month}` : month}${
day < 10 ? `0${day}` : day
}`;
};
์ํ๋ฅผ ํด๋ฆญํ๋ฉด ์์ธ์ ๋ณด๊ฐ ๋ฌ๋ค.
AxiosError: Network Error
at XMLHttpRequest.handleError (http://localhost:3000/static/js/bundle.js:80954:14)
axios๋ก API๋ฅผ ํธ์ถํ ๋ ๋ฐ์.
API์๋ฒ์ ํด๋ผ์ด์ธํธ ์๋ฒ๊ฐ ๋ฌ๋ผ์ ๋ฐ์ํจ.
์๋ฒ๋ ์๋ ์ ์์ด์ ํด๋ผ์ด์ธํธ๋จ์์ ํด๊ฒฐํด์ผ ํ๋๋ฐ ๊ฒ์ํ์๋ ๋์ค๋ withCredentials ์ต์
๋ฐฉ๋ฒ์ผ๋ก๋ ์ ํ ํด๊ฒฐ์ด ์๋ผ์ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ด ํ์ํ๋ค.
์ฐธ๊ณ ์๋ฃ https://xiubindev.tistory.com/115
์ฐธ๊ณ ๋ธ๋ก๊ทธ์ฒ๋ผ http-proxy-middleware๋ฅผ ์ฌ์ฉํด์ ํด๊ฒฐํจ
Array.map์์ async/await์ ์ฌ์ฉํ๋๋ฐ Promise๋ฐฐ์ด์ด ๋ฐํ๋จ
[Promsie, Promsie, Promise, ...]
map์์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ํ๋ ค๋ฉด Promise.all()
Promise.allSettled()
์ฒ๋ฆฌ๊ฐ ํ์ํ๋ค๊ณ ํ๋ค. ์ฐธ๊ณ ์๋ฃ๋ฅผ ํตํด์ ํด๊ฒฐํ์๊ณ ์ง๊ธ์ map ๋์ for in์ ์ฌ์ฉํ๋ ๋ฐฉํฅ์ผ๋ก ๋ฐ๊ฟจ๋ค.
์ฐธ๊ณ ์๋ฃ https://velog.io/@minsangk/2019-09-06-0209-%EC%9E%91%EC%84%B1%EB%90%A8-eik06xy8mm