2025년 7월 23일조회 561분 읽기
이론JS
JS Promise
JavaScript Promise 완벽 정리
JavaScript의 비동기 처리를 위한 핵심 개념, Promise 객체를 구조부터 메서드, 실전 예시까지 정리합니다.
📌 Promise란?
비동기 작업의 성공 또는 실패를 나타내는 미래의 값을 위한 객체
Promise는 3가지 상태(state) 를 가집니다:
pending(대기): 비동기 작업이 아직 완료되지 않은 상태fulfilled(이행): 작업이 성공적으로 완료됨rejected(거부): 작업이 실패함
🧭 상태 전이 흐름
✍️ 기본 사용법
js
const promise = new Promise((resolve, reject) => {
const success = true;
if (success) resolve("성공!");
else reject("실패!");
});
promise
.then(result => console.log(result))
.catch(err => console.error(err));
🔁 Promise 체이닝
js
fetch("/user")
.then(res => res.json())
.then(data => {
console.log("User:", data);
return fetch(`/user/${data.id}/posts`);
})
.then(res => res.json())
.then(posts => console.log("Posts:", posts))
.catch(err => console.error("오류 발생:", err));
✅ Promise 주요 메서드
1. Promise.all()
- 모든 Promise가 fulfilled 되어야 결과 반환
- 하나라도 rejected 되면 전체 reject
js
const p1 = fetch("/user");
const p2 = fetch("/config");
Promise.all([p1, p2])
.then(([r1, r2]) => Promise.all([r1.json(), r2.json()]))
.then(([user, config]) => {
console.log(user, config);
})
.catch(err => console.error("에러:", err));
✅ 실전 병렬 API 예시
js
async function loadData() {
const [user, notif, settings] = await Promise.all([
fetch("/api/user").then(res => res.json()),
fetch("/api/notifications").then(res => res.json()),
fetch("/api/settings").then(res => res.json())
]);
console.log(user, notif, settings);
}
all 중 하나 실패시
2. Promise.allSettled()
- 모든 Promise가 끝날 때까지 기다림 (성공/실패 상관 없음)
js
const tasks = [
Promise.resolve(1),
Promise.reject("오류!"),
Promise.resolve(3)
];
Promise.allSettled(tasks).then(results => {
results.forEach((result, i) => {
console.log(`작업 ${i}:`, result.status, result.value || result.reason);
});
});
3. Promise.race()
- 가장 먼저 완료된 하나만 반환
js
const fast = new Promise(resolve => setTimeout(() => resolve("fast!"), 500));
const slow = new Promise(resolve => setTimeout(() => resolve("slow..."), 2000));
Promise.race([fast, slow]).then(result => {
console.log(result); // "fast!"
});
4. Promise.any() (ES2021+)
- 성공하는 것 중 제일 먼저 반환
- 모두 실패하면
AggregateError발생
js
const t1 = Promise.reject("실패1");
const t2 = Promise.resolve("성공2");
const t3 = Promise.resolve("성공3");
Promise.any([t1, t2, t3]).then(result => {
console.log(result); // "성공2"
});
💥 예외 처리 전략
일반적인 catch
js
doSomething()
.then(result => doNext(result))
.catch(err => console.error("에러:", err));
async/await 스타일
js
async function run() {
try {
const data = await fetchData();
console.log(data);
} catch (err) {
console.error("에러:", err);
}
}
📋 정리: 언제 어떤 메서드를 쓸까?
| 메서드 | 설명 | 실패 시 행동 |
|---|---|---|
Promise.all | 모두 성공해야 다음 단계로 | 하나라도 실패 → 전체 reject |
Promise.allSettled | 성공/실패 모두 수집 | 실패해도 전체 결과 반환 |
Promise.race | 가장 먼저 완료된 하나 | 먼저 실패해도 reject 발생 |
Promise.any | 가장 먼저 성공한 하나 | 모두 실패하면 AggregateError |
📚 추가 예시: API 중 2개만 성공해도 되는 구조 만들기
js
const endpoints = ["/a", "/b", "/c"];
const tasks = endpoints.map(url =>
fetch(url).then(res => res.json()).catch(() => null)
);
Promise.allSettled(tasks).then(results => {
const valid = results
.filter(r => r.status === "fulfilled")
.map(r => r.value);
if (valid.length >= 2) {
console.log("2개 이상 성공:", valid);
} else {
console.warn("요청 대부분 실패");
}
});
🧠 결론
Promise는 JS 비동기의 핵심 도구입니다.- 병렬 처리, 대기, 복수 실패 대응 등 실무에서 다루는 다양한 케이스에 맞는 메서드를 선택하세요.
- 특히
Promise.allSettled은 요즘 안정적인 비동기 처리 전략으로 많이 쓰입니다.
📎 참고