자바스크립트에서 "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();
});
});
});
이 구조가 바로 흔히 말하는 콜백 지옥입니다.
콜백 지옥의 문제점
- 코드 가독성이 급격히 떨어집니다
- 들여쓰기가 계속 깊어지면서 흐름을 한눈에 파악하기 어렵습니다.
- 에러 처리가 까다롭습니다
- 각 단계마다 에러를 개별적으로 처리해야 해서 코드가 복잡해집니다.
- 로직의 흐름을 추적하기 힘듭니다
- 동기 코드처럼 위에서 아래로 읽는 방식이 불가능합니다.
이 문제는 자바스크립트가 규모 있는 애플리케이션으로 확장되면서 점점 더 크게 드러났습니다.
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는 반드시 짚고 넘어가야 할 개념입니다.




