Day-29 SPA vs MPA, Callback, Promise

이영주·2022년 6월 17일
0

중고마켓의 거래위치를 나타내기 위해 카카오에서 제공하는 API를 가져와서 지도를 나타내봤다.
잘되는줄 알았는데 그 페이지에서 잘나오고 다른 곳에 있다가 오면 안나오는 문제점 발견ㅠㅠ
신나있던 나를 또 기죽이게 만든.. 지도 너란 녀석..
싱글페이지랑 멀티페이지 차이를 알고 적용시켜야 한다던데 자세히 알아보자!

SPA vs MPA

 const onClickMoveToMap = () => {
 router.push("/29-03-kakao-map-routed");
 }
 
 return <button onClick={onClickMoveToMap}>맵으로 이동하기</button>

코드를 작성하고 확인했으나 위와 같은 오류가 나타났다.
하지만 아래 코드처럼 a 태그를 작성하면 잘 나오는 것이 확인이 되었다.

<button>
  <a href="29-03-kakao-map-routed">맵으로 이동하기</a>
</button>

싱글페이지 어플리케이션(SPA)과 멀티페이지 어플리케이션(MPA)의 때문인데
싱글페이지 어플리케이션(SPA)은 페이지를 다 그려놓고 이동할 부분으로 바로 이동할 수 있도록 하는 것이며 router, Link태그가 여기에 속하며,
멀티페이지 어플리케이션(MPA)은 이동을 할 때 새로 페이지를 받아와 다시 그려지기 때문에 속도가 느리고 a태그가 여기에 속한다.

📌 참고: router는 특정 로직을 처리한 후 이동이 될 때 사용하며, Link는 바로 이동이 될 때 사용한다.

이렇게 멀티페이지는 속도가 느리기 때문에 페이지가 불러오기 전에 지도가 불러와져서 보이게 된 것이며 router는 페이지 이동속도가 너무 빨라 지도를 불러오기 전에 페이지가 불러와져서 지도가 안보이게 된것이다.

해결방법!
1. 지도를 미리 다운로드 받아놓기
2. 페이지이동 후 다운도르 받을때까지 기다리기

해결방법에는 2가지가 있지만 1번은 지도로 이동하는 버튼마다 함수를 만들어놓기 번거로워서 _app에 지도를 받는 함수를 적용해야 하는데 그러면 필요없는 페이지까지 적용되니까 비효율적이기 때문에 2번 방법이 적합하다

페이지 이동 기다리기 위해서는 useEffect를 사용하면 해결이 된다!

콜백함수(Callback)

아래 함수에서 qqq 안에 function(){} 함수가 들어갈 수 있을까?

const aaa(qqq){
	qqq()
}

aaa(function(){})

aaa(() => {}) //화살표함수 //map, setTimeout 등과 같은 형태

함수안에 함수도 들어갈 수 있으며 aaa의 인자로 들어가는 function( ){}, ( ) => { } 등을 콜백함수라고 부른다.

aaa가 실행이 되고 qqq로 function( ){ }이 실행이 되기 때문에 비동기에서 동기적으로 처리가 된다.


//예시
 const onClickCallback = () => {
    const aaa = new XMLHttpRequest();
    aaa.open("get", `http://numbersapi.com/random?min=1&max=200`);
    aaa.send(); 
    aaa.addEventListener("load", (res: any) => {
      const num = res.target.response.split(" ")[0]; 

      const bbb = new XMLHttpRequest();
      bbb.open("get", `http://koreanjson.com/posts/${num}`); 
      bbb.send();
      bbb.addEventListener("load", (res) => {
        const userId = JSON.parse(res.target.response).UserId; 

        const ccc = new XMLHttpRequest();
        ccc.open("get", `http://koreanjson.com/posts?userId=${userId}`);
        ccc.send();
        ccc.addEventListener("load", (res) => {
          console.log(res); 
        });
      });
    });
  };

하지만 위의 예시처럼 함수안에 함수가 계속 들어가게 되면 콜백지옥에 빠지게 되므로 비효율적인 방식이다.

프로미스(Promise)

콜백지옥에서 벗어나기 위해서 프로미스를 사용하게 되었는데 .then과 같이 사용한다.
axios의 get방식으로 주소를 불러온 후 .then을 해주게 되면 주소를 불러오는 것을 기다렸다가 함수를 실행해준다.


//예시
const onClickPromise = () => {
  
  axios
      .get("http://numbersapi.com/random?min=1&max=200")
      .then((res) => {
        const num = res.data.split(" ")[0];
        return axios.get(`http://koreanjson.com/posts/${num}`);
      })
      .then((res) => {
        const userId = res.data.UserId;
        return axios.get(`http://koreanjson.com/posts?userId=${userId}`);
      })
      .then((res) => {
        console.log("최종결과값");
      })
}
  

최근에는 더 간단해진 async와 await 사용하며, async와 await는 아무데다 붙이지 않고 promise를 리턴해주는 axios 앞에 사용한다.

profile
= ["꼼꼼한", "프론트엔드 개발자"]

0개의 댓글