구조분해할당 callback Promise async ~ await

hyeseon han·2021년 10월 18일
0

구조분해할당(=비구조화할당)

  • 객체나 배열을 변수로 분해할 수 있게 해주는 문법
  • 함수에 객체나 배열을 전달해야 하는 경우가 있다. 전체 데이터가 아닌 일부만 필요할 때 구조분해할당을 사용한다.

key를 가진 데이터 여러개를 하나의 entity에 저장할 때 객체
collection에 데이터를 순서대로 저장할 때는 배열

객체의 구조분해할당

이름이 중요

배열의 구조분해할당

이름은 중요하지 않고 순서가 중요하다.

객체를 구조분해할당 했을 때와 배열을 구조분해할당 했을 때 가장 큰 차이점은 이름은 정할 수있다.
객체는 이름을 변경할 수 없다.

Quiz

function getClassmates(){
  
}

const [child1, child2] = getClassmates()
  1. child1에 "영희", child2에 "철수"가 할당 받을 수 있도록 함수를 완성해라.
          function getClassmates(){
            return ["영희", "철수"]
          }
          // outcome: undefined

          getClassmates()
          // outcome: ['영희', '철수']

          const [child1, child2] = getClassmates()
          // outcome: undefined

          child1
          // outcome: '영희'

          child2
          // outcome: '철수'
  1. const [child1, child2] = getClassmates("훈이", "맹구")를 실행하고 child1에 "맹구", child2에 "훈이"를 할당받을 수 있도록 함수를 완성해라
        function getClassmates(aaa,bbb){
            return [bbb, aaa]
        }
        // outcome: undefined

        const [child1, child2] = getClassmates("훈이", "맹구")
        // outcome: undefined

        child1
        // outcome: '맹구'

        child2
        // outcome: '훈이'

Callback

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

	// add 함수의 인자: x, y
        function add (x, y){
          return x + y 
        }

일반적으로 인자로 넣게 되는 것들은 문자열, 숫자열, 배열, 객체 등의 데이터이다. 하지만 "함수"도 인자에 들어갈 수 있다.

function add (x, y, callback){
  let result = x * y
}
//
function result(data){
  console.log(data, "콜백함수 실행")
}
//
add(5, 10, result)
  • add 함수에는 인자로 x, y, callback이 들어가고, callback에는 "함수"가 들어간다.
  • add 함수를 실행시키면 add 함수 안에서 인자로 들어간 다른 함수가 실행된다.
  • 이런 경우 add 함수의 인자로 사용된 result 함수를 callback 함수라고 부른다.
// 또 다른 예. map에서 함수 실행
const classmates = ["철수","영희","훈이"]
//outcome: undefined
classmates.map((el) => {return `${el}어린이`})
//outcome: ['철수어린이', '영희어린이', '훈이어린이']
classmates.map(function(el){ return `${el}어린이`})
//outcome: ['철수어린이', '영희어린이', '훈이어린이']
import axios from "axios";
import { useState } from "react";

export default function CallbackPromiseAsyncAswitPage() {
  const [myCallback, setMyCallback] = useState([]);

  // async-await 이 없었을 때
  function onClickMyCallback() {
    //   new Date() // 내장객체
    const ccc = new XMLHttpRequest();
    ccc.open("get", "http://numbersapi.com/random?min=1&max=200");
    ccc.send();
    ccc.addEventListener("load", (res) => {
      console.log(res);
      const num = res.target.response.split(" ")[0];
      //   setMyCallback(num);

      const aaa = new XMLHttpRequest();
      aaa.open("get", `http://koreanjson.com/posts/${num}`);
      aaa.send();
      aaa.addEventListener("load", (res) => {
        // console.log(JSON.parse(res.target.response).UserId);
        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);
        });
      });
    });
  }

  return (
    <>
      <span>
        결과:
        {myCallback.map((el) => (
          <div key={el.title}> {el.title}</div>
        ))}
      </span>
      <button onClick={onClickMyCallback}>Callback 요청하기!!</button>
    </>
  );
}

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

onClick, onChange 등이 이벤트이다. 이런 이벤트들은 html에서 미리 만들어 놓은 함수이다.

// 일반적인 onClick 사용
<button onClick={onClickButton}></button>

button을 클리하면 onClick함수가 실행되고 onClick에서는 다시 onClickButton을 실행한다. 1번에서 함수의 인자로 onClickButton이 들어가기 때문에 onClickButton을 callback 함수라고 부를 수 있다.(= onClickButton을 호출한다, 호출된다.)

이러한 callback 함수는 또 2가지 나뉜다.

자바스크립트는 Single-Thread / Non-Blocking 방식으로 코드를 실행한다. 즉, 자바스크립트는 한 번에 하나의 코드만 실행(Single-Thread)할 수 있다. 하지만 코드를 실행하고 해당 결과를 기다리지 않고 다음 코드를 실행(Non-Blocking)한다.

1. 동기적 함수

서버 컴퓨터가 작업이 끝날 때까지 기다리는 통신
한번에 하나씩 통신

2. 비동기적 함수

결과를 기다리지 않고 다음 코드를 실행하는 과정

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

결과

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

setTimeout을 먼저 실행시켰지만, console.log()가 먼저 결과창에 보인다.

Promise

위의 비동기적 callback을 연속적으로 계속 사용하게 되는 경우 callback 지옥에 빠지게된다.

이를 해결하기 위해 Promise를 사용한다.

axiospromise를 지원하는 라이브러리이다.

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

export default function CallbackPromiseAsyncAswitPage() {
  const [myPromise, setMyPromise] = useState([]);

  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);
      });
  }

  //   new Promise((resolve, reject) => {
  //       // 외부에 요청하기
  //       if(성공) resolve()
  //       if(실패) reject()
  //   })

  return (
    <>
      <span>
        결과:
        {myPromise.map((el) => (
          <div key={el.title}>{el.title}</div>
        ))}
      </span>
      <button onClick={onClickMyPromise}>Promise 요청하기!!</button>
    </>
  );
}

async ~ await

  • async ~ awaitPromise를 직관적이고 깔끔하게 만든다.
  • 한 줄씩 '기다린다'로 해석한다.
  • callback이나 promise와 같이 비동키 코드를 작성하는 새로운 방법이다.
  • 비동기를 유지하면서 동기적으로 코딩할 수있다.
    (동기적 코딩: 위에서 아래 흐름대로 순차적으로 진행)
  • try / catch로 에러를 핸들링할 수 있다.
  • error가 어디서 발생했는지 알기 쉽다.
import axios from "axios";
import { useState } from "react";

export default function CallbackPromiseAsyncAswitPage() {
  const [myAsyncAwait, setMyAsyncAwait] = useState([]);

  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 (
    <>
      <span>
        결과:
        {myAsyncAwait.map((el) => (
          <div key={el.title}>{el.title}</div>
        ))}
      </span>
      <button onClick={onClickMyAsyncAwait}>AsyncAwait 요청하기!!</button>
    </>
  );
}

0개의 댓글