리액트로 파이어베이스 연동중 실행 순서에 대해 .. 채택완료
react, nextjs 로 firebase 연동중에 궁금한 부분이 있어 문의 드립니다.
기초가 부족하니 부족한 부분이 많네요.
</p>
<p> </p>
<p>const [title, setTitle] = useState('')</p>
<p> const [client, setClient] = useState('')</p>
<p> const [theday, setTheday] = useState('')</p>
<p> const [tech, setTech] = useState('')</p>
<p> const [url, setUrl] = useState('')</p>
<p> // const [imgs, setImgs] = useState({imgThumb:null, imgPC:null, imgMo:null })</p>
<p> const [imgThumb, setImgThumb] = useState(null)</p>
<p> const [imgPC, setImgPC] = useState(null)</p>
<p> const [imgMo, setImgMo] = useState(null)</p>
<p> const [content, setContent] = useState('')</p>
<p> const [tags, setTags] = useState('')</p>
<p> const [cat, setCat] = useState('')</p>
<p> </p>
<p> const createProject = async () => { </p>
<p> </p>
<p> if( imgThumb != null ) {</p>
<p> let randomName = uuid();</p>
<p> const imageRef = ref(storage, `project-images/${imgThumb.name + randomName}`); </p>
<p> uploadBytes(imageRef, imgThumb).then(()=> { </p>
<p> getDownloadURL(ref(storage, `project-images/${imgThumb.name + randomName}`)).then((url)=>{ </p>
<p> setImgThumb(url)</p>
<p> })</p>
<p> });</p>
<p> }</p>
<p> </p>
<p> if( imgPC != null ) {</p>
<p> let randomName1 = uuid();</p>
<p> const imageRef = ref(storage, `project-images/${imgPC.name + randomName1}`); </p>
<p> uploadBytes(imageRef, imgPC).then(()=> { </p>
<p> getDownloadURL(ref(storage, `project-images/${imgPC.name + randomName1}`)).then((url)=>{ </p>
<p> setImgPC(url)</p>
<p> })</p>
<p> });</p>
<p> }</p>
<p> </p>
<p> if( imgMo != null ) {</p>
<p> let randomName2 = uuid();</p>
<p> const imageRef = ref(storage, `project-images/${imgMo.name + randomName2}`); </p>
<p> uploadBytes(imageRef, imgMo).then(()=> { </p>
<p> getDownloadURL(ref(storage, `project-images/${imgMo.name + randomName2}`)).then((url)=>{ </p>
<p> setImgMo(url)</p>
<p> })</p>
<p> });</p>
<p> }</p>
<p> </p>
<p> // const imgThumbUrl = await</p>
<p> </p>
<p>//글 등록전 data 세팅</p>
<p> const data = {</p>
<p> title: title,</p>
<p> client: client,</p>
<p> completedDay: theday,</p>
<p> tech: tech,</p>
<p> url: url,</p>
<p> imgThumb: imgThumb,</p>
<p> imgPC: imgPC,</p>
<p> imgMo: imgMo,</p>
<p> content: content,</p>
<p> tags: tags,</p>
<p> cat: cat,</p>
<p> author: {name: auth.currentUser.displayName, id: auth.currentUser.uid }</p>
<p> }</p>
<p> console.log( data ) </p>
<p> </p>
<p>//글등록 실행</p>
<p> try {</p>
<p> const docRef = await addDoc(collection(db, "projects"), data);</p>
<p> console.log("다음 id로 document가 생성: ", docRef.id);</p>
<p> } catch (e) {</p>
<p> console.error(e);</p>
<p> }</p>
<p> }</p>
<p>
위는 코드 중 일부분입니다. 파이어베이스에 글을 등록하려합니다.
문제 되는 부분은,
글등록 전,
const data = {} 값 세팅하는 부분인데요..
바로 위 if절 3개에서 값이 계산된 값 후, 그 값을 data에 적용하나 후,
try {
const docRef = await addDoc(collection(db, "projects"), data);
console.log("다음 id로 document가 생성: ", docRef.id);
}
가 진행이 되어야 하는데, 현재는, 바로 data 에 값이 저장되고 있습니다.
그로 인해 오류가 생기네요.
아래처럼 이 부분을 setTimeout을 하면 정상적으로 실행이 됩니다.
이 부분을 처리하려면 어떻게 해야할까요?
조언을 구해도 될까요?
고맙습니다.
</p>
<p>setTimeout(function(){</p>
<p> const data = {</p>
<p> title: title,</p>
<p> client: client,</p>
<p> completedDay: theday,</p>
<p> tech: tech,</p>
<p> url: url,</p>
<p> imgThumb: imgThumb,</p>
<p> imgPC: imgPC,</p>
<p> imgMo: imgMo,</p>
<p> content: content,</p>
<p> tags: tags,</p>
<p> cat: cat,</p>
<p> author: {name: auth.currentUser.displayName, id: auth.currentUser.uid }</p>
<p> }</p>
<p> console.log( data )</p>
<p> }, 1000)</p>
<p>
답변 1개
비동기 함수 문제이고
이런 상황에서 setTimeout 으로 임의 딜레이를 주는것은 더 알수없는 사이드이펙트를 낳을수 있습니다.
해당 딜레이는 사용자 환경에 따라 1초안에 끝날수도 있지만 10초를 넘길수도 있습니다.
다음과 같은 부분이 보이는데
</p>
<p>// const imgThumbUrl = await</p>
<p>
하시려던것 처럼 await 키워드로 처리 하거나
Promise 객체를 이용해 묶음처리 해주어야 합니다.
예제 올려드리니 응용해보시기 바랍니다.
그리고 예제에는 resolve 처리에 대한 부분만 있지만
실제는 reject 가 발생할 수도 있기 때문에 예외처리도 작업하셔야 할겁니다.
</p>
<p><script>
async function fn_a(args) {
if (args.a == null) {
// return Promise.reject(null);
return Promise.resolve(null);
}</p>
<p> return new Promise((resolve, reject) => {
const t = 1000;
setTimeout(() => {
resolve(t);
}, t);
});
}
async function fn_b(args) {
if (args.b == null) {
// return Promise.reject(null);
return Promise.resolve(null);
}</p>
<p> return new Promise((resolve, reject) => {
const t = 2000;
setTimeout(() => {
resolve(t);
}, t);
});
}
async function fn_c(args) {
if (args.c == null) {
// return Promise.reject(null);
return Promise.resolve(null);
}</p>
<p> return new Promise((resolve, reject) => {
const t = 3000;
setTimeout(() => {
resolve(t);
}, t);
});
}</p>
<p>const createProject = async () => {
const param = {
a: 1,
b: null,
c: 3,
};</p>
<p> try {
fn_a(param);
fn_b(param);
fn_c(param);</p>
<p> const data = {
a: param.a,
b: param.b,
c: param.c,
};
console.log(JSON.stringify(data));
} catch (err) {
console.error(err);
}
};</p>
<p>const createProjectA = async () => {
const param = {
a: 1,
b: null,
c: 3,
};</p>
<p> const fn_set = [];
fn_set.push(fn_a(param));
fn_set.push(fn_b(param));
fn_set.push(fn_c(param));</p>
<p> const data = {
a: param.a,
b: param.b,
c: param.c,
};</p>
<p> Promise.all(fn_set).then((values) => {
[data.a, data.b, data.c] = values;
console.log(JSON.stringify(data));
}).catch(err => {
console.error(err);
});
};</p>
<p>createProject(); // {"a":1,"b":null,"c":3}</p>
<p>createProjectA(); // {"a":1000,"b":null,"c":3000}</p>
<p></script></p>
<p>
답변에 대한 댓글 1개
댓글을 작성하려면 로그인이 필요합니다.
답변을 작성하려면 로그인이 필요합니다.
로그인