자바스크립트에서 "Promise는 왜 등장했을까?"

개발/javascript&typescript1 2025. 12. 26. 12:27

자바스크립트를 어느 정도 사용하다 보면 Promise라는 개념을 반드시 만나게 됩니다.
처음엔 문법도 낯설고, then, catch가 왜 필요한지 잘 와닿지 않는 경우도 많습니다.
Promise는 단순히 새로운 문법이 아니라, 자바스크립트가 안고 있던 구조적인 문제를 해결하기 위해 등장한 개념입니다.

Promise가 왜 필요했는지, 어떤 문제를 해결하려고 나왔는지부터 차근차근 정리해보겠습니다.

 



자바스크립트의 비동기 처리 방식부터 이해해야 합니다

자바스크립트는 기본적으로 단일 스레드 언어입니다.
한 번에 하나의 작업만 처리할 수 있기 때문에, 시간이 오래 걸리는 작업은 비동기로 처리합니다.

대표적인 비동기 작업은 다음과 같습니다.

  • 서버 통신 (Ajax, fetch)
  • 타이머 (setTimeout, setInterval)
  • 파일 읽기
  • 사용자 입력 이벤트 처리

 

이런 작업들은 결과를 바로 받을 수 없고, 나중에 결과가 돌아옵니다.
그래서 초창기 자바스크립트에서는 비동기 처리를 콜백 함수로 해결했습니다.

 



콜백 기반 비동기의 한계

가장 단순한 비동기 코드는 이런 형태입니다.

setTimeout(function () {
  console.log("작업 완료");
}, 1000);

문제는 비동기 작업이 여러 단계로 이어질 때 발생합니다.

login(user, function () {
  getUserInfo(function () {
    getUserPosts(function () {
      renderPage();
    });
  });
});

 

이 구조가 바로 흔히 말하는 콜백 지옥입니다.

 

 

콜백 지옥의 문제점

  1. 코드 가독성이 급격히 떨어집니다
  2. 들여쓰기가 계속 깊어지면서 흐름을 한눈에 파악하기 어렵습니다.
  3. 에러 처리가 까다롭습니다
  4. 각 단계마다 에러를 개별적으로 처리해야 해서 코드가 복잡해집니다.
  5. 로직의 흐름을 추적하기 힘듭니다
  6. 동기 코드처럼 위에서 아래로 읽는 방식이 불가능합니다.

 

이 문제는 자바스크립트가 규모 있는 애플리케이션으로 확장되면서 점점 더 크게 드러났습니다.

 


Promise의 등장 배경

Promise는 이런 콜백 중심 비동기 구조의 한계를 해결하기 위해 등장했습니다.

핵심 목표는 다음과 같습니다.

 

  • 비동기 작업을 하나의 "객체"로 표현
  • 성공과 실패 상태를 명확하게 구분
  • 비동기 작업을 체이닝 방식으로 연결
  • 에러 처리를 일관된 방식으로 처리

 

즉, Promise는 "미래에 완료될 작업"을 표현하는 표준화된 약속 객체라고 볼 수 있습니다.

 


 

Promise가 해결한 핵심 포인트

 

1. 상태 기반 구조

Promise는 항상 세 가지 상태 중 하나를 가집니다.

  • pending: 아직 결과가 정해지지 않은 상태
  • fulfilled: 성공적으로 완료된 상태
  • rejected: 실패한 상태

 

이 상태 개념 덕분에 비동기 작업의 생명주기가 명확해졌습니다.

 


2. then 체이닝으로 흐름을 정리

Promise를 사용하면 비동기 작업을 다음과 같이 작성할 수 있습니다.

login(user)
  .then(getUserInfo)
  .then(getUserPosts)
  .then(renderPage)
  .catch(handleError);

코드가 위에서 아래로 읽히기 때문에, 동기 코드와 거의 같은 가독성을 가집니다.

이것만으로도 Promise의 존재 이유는 충분합니다.

 


 

3. 에러 처리의 일원화

콜백 방식에서는 각 단계마다 에러 처리가 필요했지만,

Promise에서는 catch 하나로 전체 흐름의 에러를 처리할 수 있습니다.

fetchData()
  .then(processData)
  .then(saveData)
  .catch(error => {
    console.error(error);
  });

에러 처리 위치가 명확해지고, 유지보수도 훨씬 쉬워졌습니다.

 


 

4. 비동기 작업의 조합이 쉬워짐

Promise는 여러 비동기 작업을 동시에 다루는 기능도 제공합니다.

  • Promise.all
  • Promise.race
  • Promise.allSettled

 

이 덕분에 병렬 처리, 조건부 처리 같은 고급 비동기 로직도 깔끔하게 표현할 수 있게 되었습니다.


 

Promise는 끝이 아니라 출발점입니다

Promise는 비동기 처리를 혁신적으로 개선했지만, 문법 자체가 완전히 직관적이진 않았습니다.
이 한계를 보완하기 위해 등장한 것이 async / await 입니다.

async / await 역시 Promise를 기반으로 동작하며, Promise 없이는 존재할 수 없는 문법입니다.

즉, Promise는 현대 자바스크립트 비동기 처리의 기반이 되는 핵심 개념이라고 볼 수 있습니다.

 


 

정리하자면..

Promise는 단순히 새로운 문법을 추가하기 위해 등장한 기능이 아닙니다.
콜백 기반 비동기 처리의 구조적 문제를 해결하고, 자바스크립트를 대규모 애플리케이션에서도 안정적으로 사용할 수 있게 만든 핵심 장치입니다.

  • 콜백 지옥을 해결하고
  • 비동기 흐름을 명확하게 만들고
  • 에러 처리를 일관되게 관리하기 위해

 

Promise는 필연적으로 등장할 수밖에 없었습니다.

Promise를 이해하면 async / await는 훨씬 자연스럽게 따라오게 됩니다.
자바스크립트 비동기를 제대로 이해하고 싶다면, Promise는 반드시 짚고 넘어가야 할 개념입니다.

반응형
admin