테스트 사이트 - 개발 중인 베타 버전입니다

리액트로 파이어베이스 연동중 실행 순서에 대해 .. 채택완료

Mr섬띵 3년 전 조회 1,943

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개

채택된 답변
+20 포인트
3년 전

비동기 함수 문제이고

이런 상황에서 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개

M
Mr섬띵
3년 전
답변 주셔서 고맙습니다. 참고해서 해결하겠습니다. 즐거운 하루 되세요!!

댓글을 작성하려면 로그인이 필요합니다.

답변을 작성하려면 로그인이 필요합니다.

로그인