10月18日Calback、Promise、async/await


Callback?
Apiドキュメントやコンセプトコンテンツを参照すると、多くのcallback関数に触れます.
Calback関数の意味は大きく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関数で記述できます.
    非同期Calback
    非同期関数は、結果を待たずに次のコードを実行することを意味します.
    settimeOutの例
    function Test () {
    	console.log("3초 기다리기")
    }
    setTimeout(Test,3000);
    console.log('이건 바로 실행')
    結果
    "이건 바로 실행"
    "3초 기다리기"
    以上のようにsettimeoutを使用する場合、javascriptがコードを非同期で実行するため、次のコードが最初に実行されます.
    callback => promise => async/await
    しかし、上のようにcallbackを使い続けると、callback地獄に陥る.

    この部分を改善するためにpromiseが出現し,さらに発展し,現在async/awaitとして用いられている.
    コールバック、承諾、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>
        </>
      );
    }
    
    いずれも同じ結果を生み出すコードであり,コードの長さがかなり短くなっていることがわかる.