특정 데이터를 api를 call 하는 제네레이터를 사용하여 데이터를 불러오는 작업을 진행하는 데 요청사항으로 특정 url들을 base64로 인코딩을 해줘야 한다.
하지만 여기서 해당 이미지들의 url들이 우리 서버에 위치하지 않기 때문에 api를 활용하여 수정하는 작업을 진행했다.
//** 액션 타입을 지정**
export const FETCH_PRODUCTS = "blog/FETCH_PRODUCTS";
export const FETCH_PRODUCTS_SUCESS = "blog/FETCH_PRODUCTS_SUCESS";
export const FETCH_PRODUCTS_FAIL = "blog/FETCH_PRODUCTS_FAIL";
// **액션 생성 후 반환값 지정(타입스크립트)**
export const fetchProducts = createAsyncAction(
FETCH_PRODUCTS,
FETCH_PRODUCTS_SUCESS,
FETCH_PRODUCTS_FAIL
)<ProductRequest, { products: ProductsResponse }, APIError>(); //순서대로 "입력받는타입", "반환되는타입", "에러타입"
// 제네레이터 생성
function* fetchBlogSaga(action: ReturnType<typeof fetchProducts.request>) {
try {
const { data }: AxiosResponse<ProductsResponse> = yield callWrapperSaga(
blogService.getProducts,
action.payload
);
데이터를 action.payload로 받아온 후에 비구조화 할당 후 데이터 할당
yield put(fetchProducts.success({ products: data }));
} catch ({ response }) {
const { data, status } = response as AxiosResponse;
yield put(fetchProducts.failure({ data, status }));
}
}
// PRODUCTS
export const FETCH_PRODUCTS = "blog/FETCH_PRODUCTS";
export const FETCH_PRODUCTS_SUCESS = "blog/FETCH_PRODUCTS_SUCESS";
export const FETCH_PRODUCTS_FAIL = "blog/FETCH_PRODUCTS_FAIL";
export const fetchProducts = createAsyncAction(
FETCH_PRODUCTS,
FETCH_PRODUCTS_SUCESS,
FETCH_PRODUCTS_FAIL
)<ProductRequest, { products: ProductsResponse }, APIError>(); //순서대로 "입력받는타입", "반환되는타입", "에러타입"
function* fetchBlogSaga(action: ReturnType<typeof fetchProducts.request>) {
try {
const { data }: AxiosResponse<ProductsResponse> = yield callWrapperSaga(
blogService.getProducts,
action.payload
);
const dataBase64: AxiosResponse<ProductsResponse> = yield callWrapperSaga(
blogService02.getTransImageUrlLists,
data.list.map((el) => el.itemImage)
);
data.list.map((el, index: number) => {
return (el.itemImage = `data:image/*;base64,${dataBase64.data.list[index]}`);
});
yield put(fetchProducts.success({ products: data }));
} catch ({ response }) {
const { data, status } = response as AxiosResponse;
yield put(fetchProducts.failure({ data, status }));
}
}
- 첫 번째 요소는 put dispatch 를 하기 전에 해당 data의 특정 image url들을 api를 전송함으로서 재가공 해줘야함
- data를 다시 yield call 하여 데이터를 넘겨줘야함 여기서 call 부분은 커스텀하여 callWrapperSaga로 만들어줌
- 그 이후 data를 map 메서드를 활용하여 dataBase64에 index를 할당 해주면서 base64로 인코딩 해준 데이터를 새로 만들어 준다.
- yield put 디스패치를 활용하여 data를 할당 해준다.
// itemSegInfo
export const FETCH_ITEMSEG = "blogV2/FFETCH_ITEMSEG";
export const FETCH_ITEMSEG_SUCESS = "blogV2/FETCH_ITEMSEG_SUCESS";
export const FETCH_ITEMSEG_FAIL = "blogV2/FETCH_ITEMSEG_FAIL";
export const fetchItemSegInfo = createAsyncAction(
FETCH_ITEMSEG,
FETCH_ITEMSEG_SUCESS,
FETCH_ITEMSEG_FAIL
)<ProductRequest, ItemSegInfoResponse, APIError>();
// segBest
export const FETCH_SEGBEST = "blogV2/FFETCH_SEGBEST";
export const FETCH_SEGBEST_SUCESS = "blogV2/FETCH_SEGBEST_SUCESS";
export const FETCH_SEGBEST_FAIL = "blogV2/FETCH_SEGBEST_FAIL";
export const fetchSegBest = createAsyncAction(
FETCH_SEGBEST,
FETCH_SEGBEST_SUCESS,
FETCH_SEGBEST_FAIL
)<SegBestItemsRequest, SegBestResponse, APIError>();
// similarSeg
export const FETCH_SIMILAR = "blogV2/FFETCH_SIMILAR";
export const FETCH_SIMILAR_SUCESS = "blogV2/FETCH_SIMILAR_SUCESS";
export const FETCH_SIMILAR_FAIL = "blogV2/FETCH_SIMILAR_FAIL";
export const fetchSimilarSeg = createAsyncAction(
FETCH_SIMILAR,
FETCH_SIMILAR_SUCESS,
FETCH_SIMILAR_FAIL
)<SimilarSegItemsRequest, SimilarSegResponse, APIError>();
// associated
export const FETCH_ASSOCIATE = "blogV2/FFETCH_ASSOCIATE";
export const FETCH_ASSOCIATE_SUCESS = "blogV2/FETCH_ASSOCIATE_SUCESS";
export const FETCH_ASSOCIATE_FAIL = "blogV2/FETCH_ASSOCIATE_FAIL";
export const fetchAssociatedSeg = createAsyncAction(
FETCH_ASSOCIATE,
FETCH_ASSOCIATE_SUCESS,
FETCH_ASSOCIATE_FAIL
)<SimilarSegItemsRequest, any, APIError>();
// seg item info의 요청값을 받은다음 segBest, similarSeg, associated 모두 요청
export const FETCH_SEGS = "blogV2/FFETCH_SEGS";
export const FETCH_SEGS_SUCESS = "blogV2/FETCH_SEGS_SUCESS";
export const FETCH_SEGS_FAIL = "blogV2/FETCH_SEGS_FAIL";
export const fetchSegs = createAsyncAction(
FETCH_SEGS,
FETCH_SEGS_SUCESS,
FETCH_SEGS_FAIL
)<any, any, APIError>();
function* fetchSegsSaga(
action: ReturnType<typeof fetchItemSegInfo.request>
): Generator<
| AllEffect<any>
| PutEffect<PayloadAction<"blogV2/FETCH_ITEMSEG_FAIL", APIError>>
| PutEffect<PayloadAction<"blogV2/FETCH_SEGBEST_FAIL", APIError>>,
void,
[
any,
any,
AxiosResponse<AssociatedSegResponse>,
AxiosResponse<SegBestResponse>
]
> {
try {
const [itemSegInfoRes, similarSegRes, associatedSegRes] = yield all([
callWrapperSaga(blogService02.getItemSegInfo, action.payload),
callWrapperSaga(blogService02.getSimilarSegItems, action.payload),
callWrapperSaga(blogService02.getAssociatedItems, action.payload),
]);
const firstSeg = itemSegInfoRes.data.data.segData.filter(
(el: { segRank: number }) => el.segRank === 1
)[0];
const [segBestRes] = yield all([
callWrapperSaga(blogService02.getSegBestItems, {
cuid: action.payload.cuid,
date: action.payload.date,
segId: firstSeg.segId,
}),
]);
const [iBase64, siBase64, assBase64] = yield all([
callWrapperSaga(
blogService02.getTransImageUrl,
itemSegInfoRes.data.data.imageUrl
),
callWrapperSaga(
blogService02.getTransImageUrlLists,
similarSegRes.data.list.map((el: { imageUrl: string }) => el.imageUrl)
),
callWrapperSaga(
blogService02.getTransImageUrlLists,
associatedSegRes.data.list.map(
(el: { imageUrl: string }) => el.imageUrl
)
),
]);
itemSegInfoRes.data.data.imageUrl = `data:image/*;base64,${iBase64.data.data}`;
similarSegRes.data.list.map((el: { imageUrl: string }, index: number) => {
return (el.imageUrl = `data:image/*;base64,${siBase64.data.list[index]}`);
});
associatedSegRes.data.list.map(
(el: { imageUrl: string }, index: number) => {
return (el.imageUrl = `data:image/*;base64,${assBase64.data.list[index]}`);
}
);
yield all([
itemSegInfoRes && put(fetchItemSegInfo.success(itemSegInfoRes.data)),
put(fetchSimilarSeg.success(similarSegRes.data)),
put(fetchAssociatedSeg.success(associatedSegRes.data)),
put(fetchSegBest.success(segBestRes.data)),
]);
// 대표세그를 받는다
// yield put(fetchSegBest.success(segBestRes.data));
} catch (error) {
const { data, status } = error as AxiosResponse;
yield put(fetchItemSegInfo.failure({ data, status }));
yield put(fetchSegBest.failure({ data, status }));
}
}
- product data를 했을 때 처럼 데이터를 동기 작업을 진행함
문제점 발생- 데이터를 동기적으로 불러오니 순차적으로 데이터를 불러옴 이 문제로 인해 데이터를 전부 불러오는 데 시간이 너무나 딜레이가됨!
- 이 부분을 해결하기 위해 기존 동기적으로 하던 작업을 비동기적으로 변경을 함 그 부분을 해결 하기 위해 yiled all 을 활용하여 작업 진행
- 제네레이터 생성 함수의 타입을 제대로 지정을 해줘야함 -> 기존 작업시 운영 반영 문제로 제대로 정하지 않은 문제가 있음 이후 차후 운영 배포 전에 반영해야함