비동기 흐름 실습

이 페이지는 AJAX 비동기 실행콜백지옥async/await 순서로 문제와 해결을 체감하는 실습이다. 개발자도구(Console)를 열고 탭을 클릭할 때 출력 순서를 확인해보자.

핵심 개념(짧게)

AJAX (비동기 실행 확인)

Ajax 요청은 비동기적으로 실행되기 때문에, 요청을 시작한 직후에도 다음 줄 코드가 먼저 실행될 수 있다.

실행 코드(요약)

const ajaxDemo = () => {
  $(document).ready(() => {
    $.ajax({
      url: "https://jsonplaceholder.typicode.com/posts/1",
      type: "GET",
      dataType: "json",
      success: (result) => {
        console.log("실행순서 2");
        console.log(result);
        console.log("실행순서 3");
      }
    });
  });

  console.log("실행순서 1");
};

관찰 포인트

  • 콘솔에서 실행순서 1이 먼저 찍히는지 확인
  • 응답이 도착한 뒤 실행순서 2 → (result 출력) → 실행순서 3이 묶음으로 실행되는지 확인
왜 이런 순서가 나오나?

네트워크 요청은 시간이 걸릴 수 있어서, 요청을 보내고 나면 코드가 기다리지 않고 다음 줄로 진행한다. 응답이 도착하면 그때 등록된 success 콜백이 실행된다.

// 기대 관찰(예시)
// 실행순서 1
// 실행순서 2
// { ...result... }
// 실행순서 3

콜백지옥 (중첩 문제)

“이전 요청 응답을 이용해 다음 요청을 보내야 하는 상황”에서 비동기 요청을 순서대로 묶으면 success 안에 또 success가 들어가며 코드가 깊어진다.

실행 코드(요약)

const callbackHellDemo = () => {
  $(document).ready(() => {
    $.ajax({
      url: "https://jsonplaceholder.typicode.com/posts/1",
      type: "GET",
      dataType: "json",
      success: () => {
        console.log("B");
        $.ajax({
          url: "https://jsonplaceholder.typicode.com/posts/1",
          type: "GET",
          dataType: "json",
          success: () => {
            console.log("C");
            $.ajax({
              url: "https://jsonplaceholder.typicode.com/posts/1",
              type: "GET",
              dataType: "json",
              success: (result) => {
                console.log("D");
                console.log(result);
              }
            });
          }
        });
      }
    });
  });

  console.log("A");
};

관찰 포인트

  • 콘솔에서 A가 먼저 찍히는지 확인
  • 응답 흐름에 따라 B → C → D가 순서대로 찍히는지 확인
  • 요청 단계가 늘어날수록 success 중첩이 깊어져 가독성이 떨어지는지 확인
콜백지옥이 불편한 이유
  • 들여쓰기가 깊어져 읽기 어렵다.
  • 에러 처리(error)가 단계마다 반복되며 중복이 늘어난다.
  • 중간 단계 추가/삭제가 어렵다.
// 기대 관찰(예시)
// A
// B
// C
// D
// { ...result... }

async-await (가독성 개선)

async/await는 비동기 요청을 “순차 코드처럼” 작성할 수 있게 해주어, 콜백 중첩을 줄이고 유지보수를 쉽게 만든다.

실행 코드(요약)

const requestPost = () => {
  return $.ajax({
    url: "https://jsonplaceholder.typicode.com/posts/1",
    type: "GET",
    dataType: "json",
  });
};

const asyncAwaitDemo = async () => {
  const r1 = await requestPost();
  console.log("B"); console.log(r1);

  const r2 = await requestPost();
  console.log("C"); console.log(r2);

  const r3 = await requestPost();
  console.log("D"); console.log(r3);
};

$(document).ready(() => {
  asyncAwaitDemo();
  console.log("A");
});

관찰 포인트

  • A는 비동기 함수 호출 직후 먼저 찍힐 수 있음
  • await 때문에 결과 출력은 B → C → D 순서대로 보장됨
  • (원본 코드 기준) 에러는 try/catch로 한 곳에서 처리 가능
왜 A가 먼저 찍힐까?

async 함수는 호출하면 즉시 반환하고, 내부는 await 지점에서 응답을 기다렸다가 다음 줄로 진행한다. 그래서 바깥쪽 로그(A)가 먼저 찍힐 수 있다.

// 기대 관찰(예시)
// A
// B
// { ...result1... }
// C
// { ...result2... }
// D
// { ...result3... }