JavaScript 비동기 프로그래밍
Promise, Async/Await, 이벤트 루프
학습 항목
이미지 로딩 중...
JavaScript Promise 비동기 처리 완벽 가이드
Promise는 JavaScript에서 비동기 작업을 처리하는 핵심 패턴입니다. 콜백 지옥을 해결하고 더 깔끔한 비동기 코드를 작성할 수 있습니다. 실무에서 자주 사용되는 Promise 활용 패턴을 학습해보세요.
들어가며
이 글에서는 JavaScript Promise 비동기 처리 완벽 가이드에 대해 상세히 알아보겠습니다. 총 10가지 주요 개념을 다루며, 각각의 개념에 대한 설명과 실제 코드 예제를 함께 제공합니다.
목차
- Promise_기본_생성
- Promise_체이닝
- Promise.all_병렬_처리
- Promise.race_경쟁_처리
- async_await_문법
- Promise.allSettled_안전한_병렬_처리
- Promise_에러_처리
- Promise_생성자_활용
- Promise.any_첫_성공_처리
- 연속적인_비동기_작업_처리
1. Promise_기본_생성
개요
Promise는 비동기 작업의 완료 또는 실패를 나타내는 객체입니다. resolve는 성공, reject는 실패를 처리합니다.
코드 예제
const fetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = { id: 1, name: 'User' };
resolve(data);
}, 1000);
});
};
fetchData().then(data => console.log(data));
설명
new Promise로 비동기 작업을 감싸고, 1초 후 데이터를 resolve하여 성공 상태로 전달합니다. then()으로 결과를 받아 처리합니다.
2. Promise_체이닝
개요
then()을 연결하여 여러 비동기 작업을 순차적으로 처리할 수 있습니다. 각 then은 이전 결과를 받아 다음 단계로 전달합니다.
코드 예제
fetch('/api/user/1')
.then(response => response.json())
.then(user => fetch(`/api/posts/${user.id}`))
.then(response => response.json())
.then(posts => console.log(posts))
.catch(error => console.error(error));
설명
사용자 정보를 가져온 후, 해당 사용자의 게시물을 순차적으로 조회합니다. catch()로 모든 단계의 에러를 한 번에 처리합니다.
3. Promise.all_병렬_처리
개요
여러 Promise를 동시에 실행하고 모든 결과를 기다립니다. 하나라도 실패하면 전체가 실패합니다.
코드 예제
const promise1 = fetch('/api/users');
const promise2 = fetch('/api/products');
const promise3 = fetch('/api/orders');
Promise.all([promise1, promise2, promise3])
.then(([users, products, orders]) => {
console.log('모든 데이터 로드 완료');
})
.catch(err => console.error('에러 발생:', err));
설명
세 개의 API를 동시에 호출하여 가장 느린 요청이 완료될 때까지 기다립니다. 모든 요청이 성공해야 then이 실행됩니다.
4. Promise.race_경쟁_처리
개요
여러 Promise 중 가장 먼저 완료되는 것의 결과를 반환합니다. 타임아웃 구현에 유용합니다.
코드 예제
const dataPromise = fetch('/api/data');
const timeoutPromise = new Promise((_, reject) =>
setTimeout(() => reject('타임아웃'), 5000)
);
Promise.race([dataPromise, timeoutPromise])
.then(data => console.log('성공:', data))
.catch(err => console.error(err));
설명
데이터 요청과 5초 타임아웃을 경쟁시켜, 5초 안에 응답이 없으면 타임아웃 에러를 발생시킵니다.
5. async_await_문법
개요
async/await는 Promise를 더 읽기 쉽게 작성하는 문법입니다. 동기 코드처럼 보이지만 비동기로 동작합니다.
코드 예제
async function getUserData(userId) {
try {
const response = await fetch(`/api/user/${userId}`);
const user = await response.json();
return user;
} catch (error) {
console.error('에러:', error);
}
}
getUserData(1).then(user => console.log(user));
설명
await 키워드로 Promise가 완료될 때까지 기다립니다. try-catch로 에러를 동기 코드처럼 자연스럽게 처리할 수 있습니다.
6. Promise.allSettled_안전한_병렬_처리
개요
모든 Promise의 성공/실패 여부와 관계없이 모든 결과를 반환합니다. 일부 실패해도 나머지 결과를 받을 수 있습니다.
코드 예제
const promises = [
fetch('/api/users'),
fetch('/api/invalid-url'),
fetch('/api/products')
];
Promise.allSettled(promises).then(results => {
results.forEach((result, i) => {
if (result.status === 'fulfilled') {
console.log(`${i}번 성공:`, result.value);
} else {
console.log(`${i}번 실패:`, result.reason);
}
});
});
설명
세 요청 중 하나가 실패해도 나머지 두 개의 결과를 받을 수 있습니다. 각 결과의 status를 확인하여 처리합니다.
7. Promise_에러_처리
개요
catch()와 finally()를 활용하여 에러를 처리하고 정리 작업을 수행합니다. finally는 성공/실패 관계없이 실행됩니다.
코드 예제
function loadData() {
setLoading(true);
return fetch('/api/data')
.then(res => res.json())
.then(data => processData(data))
.catch(error => {
console.error('에러:', error);
showErrorMessage(error);
})
.finally(() => setLoading(false));
}
설명
데이터 로딩 시작 시 로딩 상태를 켜고, 성공하든 실패하든 finally에서 로딩 상태를 끕니다. catch로 에러를 사용자에게 표시합니다.
8. Promise_생성자_활용
개요
기존 콜백 기반 API를 Promise로 변환할 수 있습니다. setTimeout, 파일 읽기 등 다양한 비동기 작업을 Promise화할 수 있습니다.
코드 예제
function delay(ms) {
return new Promise(resolve =>
setTimeout(resolve, ms)
);
}
async function animate() {
console.log('시작');
await delay(1000);
console.log('1초 후');
await delay(1000);
console.log('2초 후');
}
설명
setTimeout을 Promise로 감싸서 delay 함수를 만들고, async/await와 함께 사용하여 순차적인 지연을 구현합니다.
9. Promise.any_첫_성공_처리
개요
여러 Promise 중 첫 번째로 성공한 결과를 반환합니다. 모두 실패해야만 에러가 발생합니다.
코드 예제
const servers = [
fetch('https://api1.example.com/data'),
fetch('https://api2.example.com/data'),
fetch('https://api3.example.com/data')
];
Promise.any(servers)
.then(response => response.json())
.then(data => console.log('가장 빠른 서버:', data))
.catch(() => console.error('모든 서버 실패'));
설명
여러 백업 서버 중 가장 먼저 응답하는 서버의 데이터를 사용합니다. 한 서버라도 성공하면 결과를 반환합니다.
10. 연속적인_비동기_작업_처리
개요
배열의 각 항목에 대해 순차적으로 비동기 작업을 수행할 때 reduce를 활용합니다.
코드 예제
async function processItems(items) {
return items.reduce(async (prev, item) => {
await prev;
const result = await fetch(`/api/process/${item}`);
console.log(`${item} 처리 완료`);
return result;
}, Promise.resolve());
}
processItems([1, 2, 3, 4, 5]);
설명
reduce로 Promise 체인을 만들어 각 항목을 순차적으로 처리합니다. 이전 작업이 완료된 후 다음 작업이 시작됩니다.
마치며
이번 글에서는 JavaScript Promise 비동기 처리 완벽 가이드에 대해 알아보았습니다. 총 10가지 개념을 다루었으며, 각각의 사용법과 예제를 살펴보았습니다.
관련 태그
#JavaScript #Promise #async/await #비동기처리 #ErrorHandling