callback, promise, async await

Cold_Rain·2024년 10월 27일

SeSAC - 프로그램🌱

목록 보기
12/13
post-thumbnail

1. callback

1-1. 특징

  • 콜백 함수는 다른 함수의 인자로 전달되어 특정 이벤트 혹은 작업이 완료된 후에 호출되는 함수를 말한다.

  • 콜백함수는 다른 함수의 인자로 전달되며 해당 함수가 완료된 후에 호출된다.

  • 주로 비동기 작업(ex. API 호출, 파일 읽기 등..)의 결과를 처리하기 위해 사용된다.

1-2. callback - code

const onClickCallback = () => {

  const aa = new XMLHttpRequest();
  aa.open("get", `http://numbersapi.com/random?min=1&max=200`);
  aa.send();
  aa.addEventListener("load", (res) => {
    console.log(res);
    const num = res.target.response.split(" ")[0]; // 랜덤숫자 저장
    console.log(num)

    // 첫 번째 요청 완료 후에 두 번째 요청 실행
    const bb = new XMLHttpRequest();
    bb.open("get", `https://koreanjson.com/posts/${num}`);
    bb.send();
    bb.addEventListener("load", (res) => {
      console.log(res);
      const userID = JSON.parse(res.target.response).UserId;  // 유저ID 저장
      console.log(userID)

      // 두 번째 요청 완료 후에 세 번째 요청 실행
      const cc = new XMLHttpRequest();
      cc.open("get", `https://koreanjson.com/posts?userId=${userID}`);
      cc.send();
      cc.addEventListener("load", (res) => {
        console.log(res.target.response);
      });
    });
  });
};
  • 1 -> 2 -> 3번을 순차적으로 요청하고 받아오는 코드다.

  • XMLHttpRequest 객체를 생성해서 API를 통해 1부터 200까지의 랜덤 숫자를 요청하고 받아오면 콜백함수가 실행되어 랜덤숫자를 저장하게 된다.

  • 1번에서 받은 값을 활용해 다른 API에서 정보를 요청한다. 요청이 완료되면 콜백함수가 실행되어 userId를 저장하는 userID가 만들어지게 된다.

  • 2번에서 요청받은 userID를 활용해 마지막 콜백함수가 실행되며 콘솔을 출력한다.

1-3. 콜백지옥 (Callback Hell)

  • 현재는 요청하는게 3개고 코드의 양이 길지 않아 괜찮은데 코드도 길어지고 요청하는 수도 많아지면 이를 콜백지옥이라고 한다.

특징

  • 여러 비동기 작업이 순차적으로 진행될때 결과를 처리하기 위한 콜백함수가 중첨되어 들여쓰기가 깊어지게 된다.
  • 중첩이 심해 코드의 흐름을 파악하기 어려워지며 가독성이 저하된다.
  • 콜백마다 에러 처리를 추가하나면 코드자체적으로 매우 복잡해질 수 있다.
  • 이를 해결하기 위해 2번과 3번에서 요약할 Promise와 async await이 생겨나게 됬다.

2. promise

2-1. 특징

  • 비동기 작업의 완료 or 실패를 나타내는 객체로, 비동기 처리를 더 간결하고 체계적으로 관리하기 위해 사용됨.
  • 프로미스는 3가지의 상태를 가진다.
    • 대기(Pending): 초기상태, 작업이 완료 되지 않은 상태
    • 이행(Fulfilled): 작업이 완료된 상태, 결과값을 가지고 있음
    • 실패(Rejected): 작업이 실패한 상태, 실패이유를 가지고 있음
  • 콜백지옥을 없애기 위해 프로미스 체이닝 방법을 통해 비동기 작업을 수행한다.

2-2. Promise chaining

const myPromise = () => {
  fetch(`http://numbersapi.com/random?min=1&max=200`)   // 첫 번째 fetch 요청
    .then((res) => res.text())                         // 응답을 텍스트로 변환
    .then((qqq) => {
      const num = qqq.split(" ")[0];                   // 랜덤 숫자 추출
      return fetch(`https://koreanjson.com/posts/${num}`);  // 두 번째 fetch 요청
    })
    .then((res) => res.json())                         // JSON으로 변환
    .then((qqq) => {
      const userId = qqq.UserId;                       // 작성자 ID 추출
      return fetch(`https://koreanjson.com/posts?userId=${userId}`); // 세 번째 fetch 요청
    })
    .then((res) => res.json())                         // JSON으로 변환
    .then((qqq) => {
      console.log(qqq);                                // 최종 결과 출력
    })
    .catch((error) => {
      console.error("Error:", error);                  // 에러 처리
    });
};

3. async await

3-1. 특징

  • 비동기 코드를 더 간결하고 동기 코드처럼 작성할 수 있게 도와준다.

  • async 키워드를 함수 앞에 붙이면 해당 함수는 항상 프로미스를 반환하게 된다.

  • 함수 내부에서 await 키워드를 사용할 수 있게 해준다.

  • await는 프로미스가 처리될 때까지 기다린 후, 완료된 값을 반환한다.

3-2. async await - code

const onClickAsyncAwait = async () => {
  const res1 = await fetch(`http://numbersapi.com/random?min=1&max=200`)
  const qqq1 = await res1.text()
  const num = qqq1.split(" ")[0]; // 랜덤숫자

  const res2 = await fetch(`https://koreanjson.com/posts/${num}`)
  const qqq2 = await res2.json()
  const userId = qqq2.userId; // 랜덤숫자

  const res3 = await fetch(`https://koreanjson.com/posts?userId=${userId}`)
  const qqq3 = await res3.json()
  console.log(qqq3)
    }
  • fetch를 사용해 1 ~ 200사이의 랜덤 숫자를 요청하고 받게되면 원하는 부분을 추출해 변수에 보관한다.
  • API에 변수를 사용해서 해당 게시물의 데이터를 가져온다. 응답을 JSON 형식으로 파싱해서 다른 변수에 보관한다.
  • 동일하게 API에 변수를 넣엇 해당 사용자가 작성한 모든 게시물 목록을 가져온다.
profile
프로그래밍 공부하는 찬우입니다👋

0개의 댓글