첫 번째 요청의 결과가 두 번째 요청에 필요한 경우 순차적으로 처리해야 한다.
async function getUserThenPosts() {
// 1단계: 현재 로그인한 사용자 정보 가져오기
const userResponse = await fetch('/me');
const user = await userResponse.json(); // 예: { id: 10, name: 'Alice' }
// 2단계: 해당 사용자의 게시글 목록 가져오기
const postsRes = await fetch(`/users/${user.id}/posts`);
const posts = await postsRes.json();
console.log(posts);
}
각 단계가 이전 단계의 결과에 의존할 때 사용한다. await 키워드로 각 비동기 작업이 완료될 때까지 기다린 후 다음 단계로 진행하여 절차적이고 예측 가능한 실행 흐름을 보장한다.
두 요청이 서로 독립적이라면 동시에 실행하여 전체 소요 시간을 줄일 수 있다.
const userPromise = fetch('/user').then(res => res.json());
const productPromise = fetch('/product').then(res => res.json());
userPromise.then(user => handleUser(user));
productPromise.then(product => handleProduct(product));
두 요청을 동시에 시작하지만 실행 순서는 보장되지 않는다. 네트워크 상황에 따라 어느 요청이 먼저 완료될지 예측할 수 없으므로 실행 순서가 중요한 경우에는 적합하지 않다.
특징
모든 Promise 가 성공해야 이행되며, 하나라도 실패하면 즉시 전체가 거부된다.
예시
async function fetchProductPage(productId) {
const [info, stock, reviewSummary] = await Promise.all([
fetch(`/api/products/${productId}`).then(r => r.json()),
fetch(`/api/products/${productId}/stock`).then(r => r.json()),
fetch(`/api/products/${productId}/reviews/summary`).then(r => r.json()),
]);
return { info, stock, reviewSummary };
}
동기성 / 비동기성
// 이미 이행된 프로미스 배열
const resolvedPromisesArray = [Promise.resolve(33), Promise.resolve(44)];
const p = Promise.all(resolvedPromisesArray);
console.log(p); // Promise { : "pending" }
setTimeout(function () {
console.log(p); // Promise { : "fulfilled", : Array[2] }
});
fulfilled 상태지만, Promise.all이 반환한 프로미스 p는 현재 콜스택이 비워진 뒤에야 이행된다.pending, setTimeout 이후에야 fulfilled가 찍힌다.
빈 iterable 인 경우에만 동기적으로 이행된다.
const p = Promise.all([]); // 즉시 이행
console.log(p); // Promise { : "fulfilled", : Array[0] }
실패 우선성
하나라도 거부하면 즉시 거부한다:
const p1 = new Promise((resolve) => setTimeout(() => resolve("하나"), 1000));
const p2 = new Promise((resolve) => setTimeout(() => resolve("둘"), 2000));
const p3 = new Promise((resolve, reject) => reject(new Error("거부")));
Promise.all([p1, p2, p3])
.then(values => console.log(values))
.catch(error => console.log(error.message)); // "거부"
각 프로미스에 catch 를 추가하면 동작을 변경할 수 있다.
Promise.all([
p1.catch(error => error),
p2.catch(error => error),
])
.then(values => {
console.log(values[0]); // "하나"
console.log(values[1]); // "둘"
});
특징
모든 Promise 의 성공/실패 여부와 관계없이 모두 완료될 때까지 기다린다.
status 와 value(성공) 또는 reason(실패) 을 포함한다Promise.all 보다 더 정교하게 비동기 관리를 할 수 있다예제
const values = await Promise.allSettled([
Promise.resolve(33),
new Promise((resolve) => setTimeout(() => resolve(66), 0)),
99,
Promise.reject(new Error("an error")),
]);
console.log(values);
// [
// {status: "fulfilled", value: 33},
// {status: "fulfilled", value: 66},
// {status: "fulfilled", value: 99},
// {status: "rejected", reason: Error: an error}
// ]
특징
가장 먼저 완료 (이행 또는 거부) 되는 Promise 의 결과를 반환한다.
예제
var p1 = new Promise((resolve) => setTimeout(() => resolve("하나"), 500));
var p2 = new Promise((resolve) => setTimeout(() => resolve("둘"), 100));
Promise.race([p1, p2]).then(value => {
console.log(value); // "둘" - p2가 더 빠름
});
reject 상황
var p3 = new Promise((resolve) => setTimeout(() => resolve("셋"), 500));
var p4 = new Promise((resolve, reject) =>
setTimeout(() => reject(new Error("넷")), 100)
);
Promise.race([p3, p4]).then(
value => console.log(value),
error => console.log(error.message) // "넷" - p4가 더 빠름
);
특징
가장 먼저 성공한 Promise 의 결과를 반환하며, 모든 Promise 가 실패해야만 거부된다.
예제
const pErr = new Promise((resolve, reject) => reject("Always fails"));
const pSlow = new Promise((resolve) => setTimeout(resolve, 500, "Done eventually"));
const pFast = new Promise((resolve) => setTimeout(resolve, 100, "Done quick"));
Promise.any([pErr, pSlow, pFast]).then(value => {
console.log(value); // "Done quick" - pFast가 가장 먼저 성공
});
모두 실패하는 경우
const failure = new Promise((resolve, reject) => reject("Always fails"));
Promise.any([failure]).catch(err => {
console.log(err); // AggregateError: No Promise in Promise.any was resolved
});
| 메서드 | 정상 완료 조건 | 실패 (reject) 조건 | 주요 사용 사례 |
|---|---|---|---|
| Promise.all() | 모두 성공 | 하나라도 실패하면 즉시 reject | 모든 데이터가 필수일 때 |
| Promise.allSettled() | 모두 완료 (성공/실패 무관) | reject 없음 (항상 fulfill) | 부분적 실패를 허용할 때 |
| Promise.race() | 가장 먼저 완료된 것 | 가장 먼저 완료된 것이 실패면 reject | 타임아웃 구현, 빠른 응답 우선 |
| Promise.any() | 가장 먼저 성공한 것 | 모두 실패해야 reject | 대체 경로가 있을 때 (fallback) |