자바스크립트의 비동기 처리는 처음엔 `setTimeout()` -> 콜백(callback)으로 시작하지만,
복잡한 로직이 늘어날수록 콜백이 중첩되고 코드 가독성이 급격히 나빠짐
이 문제를 해결하기 위한 것이`Promise`객체임
1. Promise란?
Promise는 "결과를 나중에 약속하는 객체"임
쉽게 말해, 비동기 작업이 끝나면 성공(`resolve`) 혹은 실패(`reject`)를 알려주는 약속임
const promise = new Promise((resolve, reject) => {
// 비동기 작업을 수행하는 함수 (executor)
setTimeout(() => {
console.log("안녕!");
resolve("안녕!"); // 성공했을 때
// reject("에러 발생"); // 실패했을 때
}, 2000);
});
- `new Promise()`안에는 "executor 함수"가 들어가고, 그 안에서 비동기 작업을 실행함
- 성공하면 `resolve(결과값)`을, 실패하면 `reject(에러 메세지)`를 호출함
물론 위 코드는 기본적인 이해를 돕기위한 코드임 아래로 넘어가서 제대로 보겠음
2. Promise의 상태 변화
`Promise`는 3가지의 상태를 가짐
| 상태 | 의미 |
| `pending` | 비동기 작업이 아직 끝나지 않음 |
| `fulfilled` | `resolve()`가 호출되어 성공함 |
| `rejected` | `reject()`가 호출되어 실패함 |
setTimeout(() => {
console.log(promise);
}, 3000);
// Promise { '안녕!' }
2초 후엔 `resolve("안녕!")`이 실행돼서 `Promise`의 상태가 `fulfilled`로 바뀌고, 그 결과로 `"안녕!"`이 담겨있음
3. then()과 catch() - 결과값을 다루는 방법
Promise는 단독으로는 약속만 한 상태임.
실제 결과를 얻으려면 `.then()`과 `.catch()`를 사용해야함
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
const num = null;
if (typeof num === "number") {
resolve(num + 10);
} else {
reject("num이 숫자가 아님");
}
}, 2000);
});
promise1
.then((value) => {
console.log(value); // resolve가 호출될 때 실행
})
.catch((error) => {
console.log(error); // reject가 호출될 때 실행
});
- `then()`은 성공했을 때 실행되는 함수
- `catch()`는 실패했을 때 실행되는 함수
- 즉, 성공과 실패를 깔끔하게 분리할 수 있게 해주는 구조가 바로 `Promise`의 핵심
맨 처음 예시 들었던 것은 `resolve`와 `reject`의 개념을 간단하게 표현하려고 보여준 예시일 뿐이니 이런식으로 사용된다고 생각하면 됨.
4. Promise 체이닝
Promise의 진짜 장점은 "비동기 작업을 순차적으로 연결"할 수 있다는 점임
이전 콜백 방식이라면 콜백 안에 콜백을 넣어야 했지만, 콜백 지옥이 만들어지는 단점이 있었음.
이젠 `.then()`을 이어 붙이는 것만으로 순서를 표현할 수 있음
function add10(num1) {
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
if (typeof num1 === "number") {
resolve(num1 + 10);
} else {
reject("num1이 숫자가 아님");
}
}, 2000);
});
return promise2;
}
add10(0)
.then((result) => {
console.log(result); // 10
return add10(result);
})
.then((result) => {
console.log(result); // 20
return add10(result);
})
.then((result) => {
console.log(result); // 30
return add10(undefined); // 일부러 에러 발생
})
.catch((error) => {
console.log(error); // "num1이 숫자가 아님"
});
// (2초 후) 10
// (4초 후) 20
// (6초 후) 30
// (8초 후) num1이 숫자가 아님
- 각 `.then()`은 이전 Promise의 결과를 받아 다음 작업에 넘겨줌
- 중간에 에러가 나면 `.catch()`로 자동 이동해서 에러를 한 번에 처리할 수 있음
- 이렇게 하면 콜백 지옥 없이 비동기 작업을 깔끔하게 순차 실행할 수 있음
이게 위 코드를 콜백 지옥으로 표현한 코드임
// 콜백 지옥 구조
add10(0, (err, result1) => {
if (err) return console.log(err);
console.log(result1); // 10
add10(result1, (err, result2) => {
if (err) return console.log(err);
console.log(result2); // 20
add10(result2, (err, result3) => {
if (err) return console.log(err);
console.log(result3); // 30
add10(undefined, (err, result4) => {
if (err) return console.log(err); // num이 숫자가 아님
console.log(result4);
});
});
});
});
지금은 짧아서 체감이 덜되지만, 저 `add10`이 계속해서 `result100`까지 간다고 생각하면 끔찍함.
다음은 이 Promise를 더 간결하게 다루는 `async`와 `await` 문법을 공부해보겠음
'React > JavaScript 심화' 카테고리의 다른 글
| [JavaScript 심화] 고차함수 총정리(복습) (0) | 2025.12.03 |
|---|---|
| [JavaScript 심화] 비동기 - async/await (0) | 2025.11.11 |
| [JavaScript 심화] 비동기 - 콜백 함수 (0) | 2025.11.11 |
| [JavaScript 심화] 동기와 비동기 (0) | 2025.11.11 |
| [JavaScript 심화] Date 객체 (0) | 2025.11.11 |