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