[CS] 콜백함수의 역사

Logun·2023년 8월 20일
0

CS

목록 보기
4/17
post-thumbnail

✅ 진화과정

함수의 인자로 들어가는 함수를 콜백함수라 하고, 실행 권한을 넘기는 것이다. 콜백함수 => Promise => Await로 진화하였는데 그 과정을 살펴기 전에 동기 비동기에 대해서 알아보자.

  • 동기 vs 비동기

    ✌️ javascript (동기적)
    => 등록 후 바로 불러오기 순으로 순차적인 작업이 필요할 때

    ✌️ axios 등의 외부 설치프로그램 (비동기)
    => 동시에 여러 일을 할 때 사용한다.

  • 비동기 함수

    비동기 함수에서
    언젠가는 돌려받을 데이터인데 아직 돌려받지 못한 상태

  • 비동기 함수의 3가지 상태

    ✌️ fulfilled: 요청이 성공한 상태
    ✌️ pending: 요청에 대한 응답을 기다리고 있는 상
    ✌️ rejected: 요청이 실패한 상태

    const promiseTest = function() ⇒ {
    	return new Promise((resolver, reject) ⇒ {
    		setTimeout(()⇒{
    			resolver(100); 
                // 2초가 지나기 전에는 pending 상태가 됨
                // fulfilled 와 100을 응답으로 가져감
    			// reject(`error`) //실패하였을 때 받아옴
    		}, 2000);
    	});
    }
    
    promiseTest().then((res)⇒{
    	console.log(res);
    });

    ✌️ pending 상태가 지나고, fulfilled가 되면 then이 실행 응답을 받아올 수 있다.

동기 비동기의 대한 기본적인 지식이 있어야 이해하기 수월하다.


✅ Callback

  • 실행코드

    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
        <script>
          function addEventListener(aaa, bbb) {
            // 셋팅된 API 주소로 요청!!
            const res = 70; //셋팅된 API 주소로부터 받아온 결과
    
            if (aaa === "load") {
              bbb(res);
            }
          }
    
          // 실행 제어권을 넘긴다. 콜백함수! aaa야 콜백함수줄테니 실행시켜줘!
    
          const myCallback = () => {
            const aa = new XMLHttpRequest();
            aa.open("get", `http://numbersapi.com/random?min=1&max=200`);
            aa.send();
            aa.addEventListener("load", (res) => {
              console.log("res:", res); //API 요청 결과
              const num = res.target.response.split(" ")[0]; // 랜덤숫자
    
              const bb = new XMLHttpRequest();
              bb.open("get", `https://koreanjson.com/posts/${num}`);
              bb.send();
              bb.addEventListener("load", (res) => {
                console.log("resbb:", res); //API요청 결과
                const userId = JSON.parse(res.target.response).UserId; //  8(작성자 ID)
    
                const cc = new XMLHttpRequest();
                cc.open("get", `https://koreanjson.com/posts?userId=${userId}`);
                cc.send();
                cc.addEventListener("load", (res) => {
                  console.log(res); //최종 API 요청 결과
                });
              });
            });
          };
  • 콜백지옥

    ✌️ 위처럼 코드가 복잡해져 이 해결방안으로 Promise가 나오고 프로미스 체이닝(promise chaining)이 나온다.

    ✌️ 프로미스 체이닝은 result가 .then 핸들러의 체인(사슬)을 통해 전달된다는 점에서 착안한 아이디어이다.


✅ Promise

Promise를 정의하고 정의할 때에 인자 값으로 resolve(res), reject(rej) 인자 값을 전달한다. 안에서 res로 어떠한 값을 전달하고, rej는 에러를 전달한다. Promise 수행은 promise 객체를 담은 변수에 .then을 사용하여 전달받은 data를 console.log(data)로 콘솔창에 출력하는 것을 볼 수 있다. then은 작업수행이 완료되면 실행이 되게 된다.
=> axios, fetch(자바스크립트 내장) 등 => 대표적인 Promise를 지원하는 기능
fetch 사용법

  • 실행코드

    new Promise((성공했을때실행시킬함수, 실패했을때실행시킬함수) => {
       try {
       //여기서 API 요청을 한다면??
       const response = "철수"; //  백엔드에서 "철수" 데이터 받아옴
       성공했을때실행시킬함수(); //성공하면 이거
      } catch (error) {
        실패했을때실행시킬함수(); // 실패하면 이거 실행
      }
  • axios 사용

    const myPromise = () => {
       axios.get(`http://numbersapi.com/random?min=1&max=200`).then((qqq) => {
         axios.get(`http://numbersapi.com/random?min=1&max=200`).then((qqq) => {
           axios.get(`http://numbersapi.com/random?min=1&max=200`).then((qqq) => {
                  //  qqq최종결과
           });
         });
       });    
     };
  • 위 코드를 아래와 같이 바꿀 수 있음

            console.log("1번째로실행");
            axios
              .get(`http://numbersapi.com/random?min=1&max=200`)
              .then((qqq) => {
                console.log("2번째로실행");
    
                return axios.get(`http://numbersapi.com/random?min=1&max=200`);
              })
              .then((qqq) => {
                console.log("3번째로실행");
    
                return axios.get(`http://numbersapi.com/random?min=1&max=200`);
              })
              .then((qqq) => {
                //  qqq최종결과
                console.log("4번째로실행");
              });
            console.log("5번째로실행");
          };

✅ AsyncAwait

async 와 await은 Promise를 조금 더 간편하게 사용 할 수 있도록 도와주며 동기적으로 실행되는 것 처럼 보이게 하는 문법이다.

  • 코드사용
    const myAsyncAwait = async () => {
        await axios.get(`http://numbersapi.com/random?min=1&max=200`);
        await axios.get(`http://numbersapi.com/random?min=1&max=200`);
        await axios.get(`http://numbersapi.com/random?min=1&max=200`);
    };
  • 에러처리
    try{
        await axios.get(`http://numbersapi.com/random?min=1&max=200`)
    } catch(error){
      console.log("error::",error)
    }
  • 주의사항
    AsyncAwait를 사용하지 않으면 TRY CATCH에 잡히게 않는다. 에러를 잡기도 전에 지나가기 때문이다.
profile
로건의 개발이야기

0개의 댓글