[TIL] 10월 18일 Callback,promise,async/await

기록하며 공부하자·2021년 10월 23일
0

Callback?

Api문서를 찾아보거나, 개념적인 내용을 찾아볼때 Callback 함수란 말을 많이 접할수 있게된다.

Callback 함수의 의미는 크게 2가지 이다.

  1. 다른 함수의 인자로 이용되는 함수

  2. 이벤트에 의해 호출되는 함수

다른함수의 인자로 인용될때

다른함수의 인자로 들어갈때의 예시는 아래와 같다.

function add (x, y, callback){
	let result = x * y
	callback(result)
}
function result (data) {
	console.log(data, "콜백함수 실행")
}
add(5, 10, result)

add 란 함수의 인자로 callback이란 함수가 들어가 있고 함수 내부에서 callback(result) 로 실행되고 있다.

이벤트에 의해 호출되는 함수

onClick, onChange 등을 사용할때의 예시를 살펴보면,

<button onClick={handleClickFunction}></button>

onClick 함수 안에서 handleClickFunction 이란 함수를 인자로 불러오기에 callback 함수로 이야기 할수 있다.

비동기적 Callback

비동기적 함수는 결과를 기다리지 않고 다음코드를 실행하는것을 의미한다.

setTimeOut 예시

function Test () {
	console.log("3초 기다리기")
}
setTimeout(Test,3000);
console.log('이건 바로 실행')

결과

"이건 바로 실행"
"3초 기다리기"

위처럼 setTimeout을 사용하면 자바스크립트가 비동기적으로 코드를 실행시키기에 아래코드가 먼저 실행된다.

callback => promise => async/await

하지만 위에처럼 callback을 연속적으로 사용하면 callback 지옥에 빠지게 된다.

이부분을 개선하기 위해서 promise가 나왔고, 그것이 더 발전해 현재는 async/await로 사용되고 있다.

callback, promise, async/await 예제코드

import axios from "axios";
import { useState } from "react";

export default function CallbackPromiseAsyncAwaitPage() {
  const [myCallback, setMyCallback] = useState([]);
  const [myPromise, setMyPromise] = useState([]);
  const [myAsyncAwait, setMyAsyncAwait] = useState([]);

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

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

        const aaa2 = new XMLHttpRequest();
        aaa2.open("get", `http://koreanjson.com/posts?userId=${user}`);
        aaa2.send();
        aaa2.addEventListener("load", (res2) => {
          const result = JSON.parse(res2.target.response); // 특정 유저가 작성한 다른 게시물 목록
          setMyCallback(result);
        });
      });
    });
  }

  function onClickMyPromise() {
    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((res2) => {
        const user = res2.data.UserId;
        return axios.get(`http://koreanjson.com/posts?userId=${user}`);
      })
      .then((res3) => {
        setMyPromise(res3.data);
      })
      .catch((error) => {
        console.log(error);
      });
  }

  async function onClickMyAsyncAwait() {
    const res1 = await axios.get("http://numbersapi.com/random?min=1&max=200");
    const num = res1.data.split(" ")[0];

    const res2 = await axios.get(`http://koreanjson.com/posts/${num}`);
    const user = res2.data.UserId;

    const res3 = await axios.get(`http://koreanjson.com/posts?userId=${user}`);
    setMyAsyncAwait(res3.data);
  }

  return (
    <>
      <h1>콜백과 친구들</h1>
      <span>
        결과:{" "}
        {myCallback.map((el) => (
          <div key={el.title}>{el.title}</div>
        ))}
      </span>
      <button onClick={onClickMyCallback}>Callback 요청하기!!</button>
      <span>
        결과:
        {myPromise.map((el) => (
          <div key={el.title}>{el.title}</div>
        ))}
      </span>
      <button onClick={onClickMyPromise}>Promise 요청하기~</button>
      <span>
        결과:
        {myAsyncAwait.map((el) => (
          <div key={el.title}>{el.title}</div>
        ))}
      </span>
      <button onClick={onClickMyAsyncAwait}>AsyncAwait 요청하기~</button>
    </>
  );
}

모두 동일한 결과를 내는 코드인데 코드의 길이가 상당히 짧아지는것을 볼수 있다.

profile
프론트엔드 개발자 입니다.

0개의 댓글