[프로젝트][에러] 동기, 비동기
문제상황 : 도서등록 페이지에서 도서 등록을 한 후에 usenavigate로 등록버튼을 누르면 사용자가 업로드했던 도서리스트및 도서검색 페이지가 쭉 뜨고, 방금전등록한 도서가 가장 최신업로드로 나와야하나, 한박자 늦게 새로고침을 해야지 업로드가 되어있는 상황을 직면
에러원인 : post요청은 오래걸리는 요청이다. 비동기적으로 실행된다. 그렇기에 async await을 사용했던것. 하지만 적절하게 사용하지못해서 생긴 에러다.
좀더 풀어 말하자면.
http요청 코드를 순차적으로 돌리기위해서는 async핸들링을 해줘야되는데
(Async await…이런걸로) 핸들링을 해주는 응답이 오기를 기다린 후에
그다음에 use navigate가 실행해야되는데 응답오기전.
post요청이 가고있는중에 navigate가 먼저 실행이된거
리스트 입장에서는 새롭게 업데이트 할것이 없기에 안되어있다가 새로고침을 하면? post요청이 끝나서 새롭게업데이트된것
원인 해결:
Settimeout을 써야겠다했는데 찾아보니 아주 안좋은 방법이라고한다.
프로미스 핸들링을 해서 async awiat을 비동기를 동기적로 해야됨. 이것은 원래 하고있던 방식이지만 제대로 못썼기에 잘안돌아갔던것이다.
이전코드 :
//api.ts
export const postContent = async (body: any, token: string) => {
try {
await axios.post(`${URL}/product/post`, body, { headers: { Authorization: `jwt ${token}` } });
} catch (e) {
throw e;
}
};
//upload.tsx
const postData = async () => {
const { title, content, img, quality } = getValues();
const formData = new FormData();
formData.append("title", title);
formData.append("content", content);
formData.append("file", img[0]);
formData.append("quality", quality);
formData.append("lat", String(latitude));
formData.append("lon", String(longtitude));
formData.append("address", address);
postContent(formData, token || "token");
};
const onSubmit = async () => {
const { quality } = getValues();
if (quality === null) {
return Swal.fire({
text: "상품 상태를 선택해주세요",
confirmButtonText: "확인",
confirmButtonColor: "#2f6218",
icon: "warning",
});
}
try {
console.log("hi");
await postData();
navigate("/search");
} catch (e) {
throw e;
}
console.log(quality);
setTitle(title);
setContent(content);
};
수정코드 :
//api.ts
export const postContent = async (body: any, token: string) => {
try {
let resp = await axios.post(`${URL}/product/post`, body, { headers: { Authorization: `jwt ${token}` } });
return resp.status;
} catch (e) {
throw e;
}
};
//upload.tsx
const postData = async () => {
return new Promise(async (res, rej) => {
const { title, content, img, quality } = getValues();
const formData = new FormData();
formData.append("title", title);
formData.append("content", content);
formData.append("file", img[0]);
formData.append("quality", quality);
formData.append("lat", String(latitude));
formData.append("lon", String(longtitude));
formData.append("address", address);
let status = await postContent(formData, token || "token");
if (Number(status) < 300) {
res(true);
} else {
rej(false);
}
});
};
const onSubmit = async () => {
const { quality } = getValues();
if (quality === null) {
return Swal.fire({
text: "상품 상태를 선택해주세요",
confirmButtonText: "확인",
confirmButtonColor: "#2f6218",
icon: "warning",
});
}
try {
let successful = await postData();
if (successful) {
navigate("/search", { replace: true });
}
} catch (e) {
throw e;
}
우선 이전처럼 submit이되면 postData를 실행시켜준다. 응답으로 status를 받고 성공이냐 아니냐에따라서 성공일시에만 navigate를 해주는방법으로 작성했다. 들어온 응답은 프로미스객체이기에 resolve reject를 써서 작성해봤다.
예전 이론에서만 배웠고, resolve reject는 프로젝트를 하면서 처음 써본것같다