개발/Javascript

[ES6][중급반] Step 4. 비동기 프로그래밍 1: Promise와 콜백 지옥 탈출

ophelisis 2025. 12. 24. 10:11
반응형

1. 비동기란 무엇인가? (Blocking vs Non-blocking)

자바스크립트 엔진은 한 번에 하나의 작업만 수행할 수 있습니다. 하지만 네트워크 요청이나 타이머 같은 작업은 시간이 오래 걸립니다.

  • 동기(Synchronous): 앞선 작업이 끝날 때까지 다음 작업을 멈추고 기다립니다. (화면 멈춤 현상 발생)
  • 비동기(Asynchronous): 작업을 요청한 뒤, 결과가 나오기 전이라도 다음 코드를 먼저 실행합니다.

2. 콜백 지옥 (Callback Hell)

Promise가 등장하기 전에는 비동기 처리를 위해 함수 안에 함수를 계속 중첩시키는 '콜백' 방식을 사용했습니다. 이는 가독성을 해치고 에러 처리를 매우 어렵게 만듭니다.

JavaScript
 
// ❌ 콜백 지옥의 예시
getData(function(a) {
  getMoreData(a, function(b) {
    getEvenMoreData(b, function(c) {
      console.log(c);
    });
  });
});

3. Promise: 비동기의 약속

Promise는 비동기 작업의 최종 완료 또는 실패를 나타내는 객체입니다. "지금은 없지만, 나중에 결과값을 줄게"라는 약속과 같습니다.

3-1. Promise의 3가지 상태 (States)

  1. Pending (대기): 이행하거나 거부되지 않은 초기 상태.
  2. Fulfilled (이행): 연산이 성공적으로 완료됨 (resolve 호출).
  3. Rejected (거부): 연산이 실패함 (reject 호출).

3-2. 기본 사용법

JavaScript
 
const myPromise = new Promise((resolve, reject) => {
  const success = true;
  setTimeout(() => {
    if (success) resolve("성공!");
    else reject("실패...");
  }, 1000);
});

myPromise
  .then(value => console.log(value))  // 성공 시 실행
  .catch(error => console.error(error)) // 실패 시 실행
  .finally(() => console.log("종료"));   // 무조건 실행

4. Promise Chaining (프로미스 체이닝)

여러 개의 비동기 작업을 순차적으로 수행해야 할 때, .then()을 연결하여 콜백 지옥을 해결할 수 있습니다. 각 .then()은 새로운 Promise를 반환하기 때문입니다.

JavaScript
 
fetchData()
  .then(data => processData(data))
  .then(processed => saveData(processed))
  .then(() => console.log("모든 작업 완료!"))
  .catch(err => console.log("중간에 에러 발생:", err));

5. Promise의 정적 메서드 (Static Methods)

병렬로 여러 비동기 작업을 처리할 때 유용한 메서드들입니다.

  • Promise.all([p1, p2, ...]): 모든 프로미스가 성공해야 성공. 하나라도 실패하면 즉시 거부.
  • Promise.allSettled([p1, p2, ...]): 성공/실패 여부와 상관없이 모든 결과가 결정될 때까지 기다림.
  • Promise.race([p1, p2, ...]): 가장 먼저 완료되는 프로미스의 결과를 반환.

💡 시니어의 조언: Promise는 단순한 콜백 대체제가 아니다

Promise는 비동기 작업을 **값(Value)**으로 취급할 수 있게 해준다는 점이 가장 중요합니다. 변수에 담을 수도 있고, 함수의 인자로 넘길 수도 있습니다. 이는 비동기 로직을 구조화하고 관리하는 방식 자체를 근본적으로 바꿔놓았습니다.

반응형