김데이의 개발공부

[ WIL ] (도저히 이해가 안가서 GPT와 만든) 비동기 처리 특집!🤖 본문

코드잇 Node.js(BE) 부트 캠프/WIL (Weekly I Learn) 📚

[ WIL ] (도저히 이해가 안가서 GPT와 만든) 비동기 처리 특집!🤖

theday365 2025. 9. 28. 14:31
반응형

진짜 정말 아무리 공부해도 비동기는 매번 난해합니다.
지금까지 비동기 자체만 최소 5번은 공부한거 같은데.. 만나면 늘 새로운 녀석 😵‍💫
 
그래서 GPT와 함께 공부 한 내용을 같이 공유 해 드립니다!
 
우선, 바쁜 분들을 위한 10줄 요약! 

[ 최종 핵심 요약 ] 

  • 비동기가 왜 생긴 걸까?
    : JavaScript는 싱글 스레드(작업 라인이 1개)임 → 중간에 오래 걸리는 작업이 있으면 화면 멈춤 → 따라서 비동기 작업 환경이 필요했고, 비동기 작업의 상태와 결과를 관리하기 위해 Promise가 등장.
  • 실무에서 "new Promise" 비동기 선언 방식을 어떻게 사용하나?
    : 공부할 때 배우는 new Promise는 원리를 배우기 위한 연습용이며, 실제론 API들이 이미 Promise 작업을 해서 반환.
  • 그럼 Promise작업을 API가 다 하는데, [ .then().catch().finaly() ] 과 [ async / await ]는 왜 알아야 하나?
    API 내부에서 비동기 작업을 처리하고, 그 결과를 Promise 객체로 감싸서 반환함.
    따라서 개발자들이 해당 데이터를 사용하기 위해서 해당 구문을 사용하며,
    그 중에서 [ async / await ] 은 기존 문법인 [ .then().catch().finaly() ] 의 사용성&가독성을 높인 신규 문법.
  • 결국 비동기의 핵심은? "시간이 오래 걸리는 일을 막히지 않고 처리하는 것"

 


📌 1. 비동기를 왜 하는가?

  • JavaScript는 싱글 스레드(작업 라인이 1개) 라 한 번에 한 작업만 처리.
  • 만약 네트워크 요청 같은 오래 걸리는 일을 동기적으로 한다면? → 그 동안 화면이 멈춤 🛑
  • 그래서 비동기를 씀 → "느린 작업은 맡겨두고, 다른 일은 먼저 처리"
  • 예시:
    • 로그인 API 호출 → 서버 응답 기다리는 동안 화면에 스피너(로딩 아이콘) 띄움
    • 이미지 여러 개 로딩 중 → 다 올 때까지 멈추지 않고, 먼저 온 것부터 화면에 뿌려줌
동기 / 비동기 비교 설명
동기 / 비동기 비교 설명, 작업 3이 비동기 작업에 걸리며 작업 4가 같이 실행되어 전체 작업이 동기 작업보다 빨리 끝남

📌 2. 비동기의 단계별 설명과 관련 문법?

1. Promise의 상태 

pending (대기 중) fulfilled (성공, 이행됨) rejected (실패, 거부됨)
  • new Promise(...)를 실행하면 처음 가지고 있는 상태.
  • 아직 결과가 정해지지 않음.
    (성공할 수도, 실패할 수도 있는 상태)
  • resolve(value)가 호출되면 fulfilled로 바뀜.
  • 이때 value는 .then()으로 전달됨.
  • reject(error)가 호출되면 rejected로 바뀜.
  • 이때 error는 .catch()로 전달됨.

 
 
2. Promise 상태 전이 

  • pending에서 → fulfilled 또는 rejected 둘 중 하나로 단 한 번만 바뀔 수 있음.
  • 일단 상태가 정해지면(fulfilled/rejected) 다시 다른 상태로 변할 수 없음 ❌
pending ── resolve() ──▶ fulfilled
       └─ reject() ───▶ rejected

 
 
3. Promise 메서드 

.then(onFulfilled) .catch(onRejected) .finally(onFinally)
  • fulfilled 상태가 되면 실행됨.
  • resolve()에서 넘긴 값이 여기로 옴.
  • rejected 상태가 되면 실행됨.
  • reject()에서 넘긴 에러가 여기로 옴.
  • 성공/실패 상관없이 무조건 마지막에 실행.
  • 주로 로딩바 끄기, 자원 정리 같은 용도

 
 
4. Promise 처리 순서 with 사과를 사자! 🍎

Promise의 작업 순서와 각 상태 변화 과정의 예시
Promise의 작업 순서와 각 상태 변화 과정의 예시
new Promise((resolve, reject) => {
   // 데이터를 받기 위해 접속 , Pending 상태 = 마트에 들어감
  
  // fulfilled 상태 = 사과가 있어서 사기로 함
  .then((value) => {
    console.log("데이터 받음", value); // = 사과를 장바구니에 담는다
  })

  // rejected 상태 = 사과가 없어서 못 산다
  .catch((err) => {
    console.error("데이터 못받음", err); // = 사과가 없는 비상상황 발생
  })
  
  // 어떠하던 결국 최종 결론 = 장바구니에 담은 거 결제하고 집 가자
  .finally(() => {
    console.log("데이터 주고 받기 끝");
  });

📌 3. 개발자가 비동기를 사용하는 시점과 어떻게 사용하는가?

1. 개발자의 비동기 사용 시점

언제
  • I/O 작업 (서버 통신, 파일 읽기, DB 조회, 이미지 로딩 등 → 시간이 걸리는 일들)
  • UI 끊김 없이 사용자 경험을 부드럽게 유지하고 싶을 때
어떻게
  • 직접 new Promise 만들어 쓰기도 하지만, 대부분은 라이브러리/브라우저 API가 Promise를 반환해줌
    [예시] fetch(), navigator.geolocation.getCurrentPosition() → Promise 기반 API
  • 개발자는 그 Promise를 .then/catch나 async/await으로 받아 처리


그럼 혹여나 써야 한다면 Promise + setTimeout은 꼭 같이 써야하는 구조인가?

Promise 예시에 항상 setTimeout의 구문이 등장하는 쓰는 이유

  • setTimeout은 가장 단순한 "지연되는 작업을 만들 수 있는 시뮬레이션"
  • 실제론 네트워크 요청(fetch) 같은 걸 보여주는 "연습용 예시"일 뿐.

 
👉 결론: 결국 실제 개발할 때는 Promise를 직접 선언할 일은 거의 없음. new Promise를 배우는 건 원리를 이해하기 위함이며, 함께 사용하는 setTimeout 또한 비동기 상태를 만들기 위한 작업일 뿐!
 


📌 4. Promise 문법과 async/await 문법의 관계

  • async/await은 그냥 Promise의 문법적 설탕(syntactic sugar).
  • 내부적으로는 여전히 Promise가 동작.
  • 차이점은 코드가 "동기처럼 보이는" 구조가 된다는 것.
// Promise 버전
fetch("/api/user")
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => console.error(err));

// async/await 버전
try {
  const res = await fetch("/api/user");
  const data = await res.json();
  console.log(data);
} catch (err) {
  console.error(err);
}

 
정리 끝! 

반응형