async/await
2025. 3. 30. 22:45ㆍWeb Development/JavaScript
async/await
ES2017에서 도입된 async/await는 Promise를 기반으로 하지만, 더 간결하고 동기식 코드와 유사한 방식으로 비동기 코드를 작성할 수 있게 해줍니다.
async/await 기본 문법
// async 함수 선언
async function fetchUserData() {
try {
// await는 Promise가 이행될 때까지 기다림
const response = await fetch('https://api.example.com/users');
if (!response.ok) {
throw new Error(`HTTP 오류! 상태: ${response.status}`);
}
const userData = await response.json();
console.log('사용자 데이터:', userData);
return userData;
} catch (error) {
console.error('데이터 가져오기 오류:', error);
throw error; // 오류 다시 던지기
}
}
// async 함수 호출 (결과는 Promise)
fetchUserData()
.then(data => {
console.log('처리된 데이터:', data);
})
.catch(error => {
console.error('최종 오류 처리:', error);
});
// 화살표 함수로도 가능
const fetchUsers = async () => {
const response = await fetch('https://api.example.com/users');
return response.json();
};
Promise 체인을 async/await로 변환
Promise 체인을 async/await를 사용하여 더 읽기 쉽고 직관적인 코드로 변환할 수 있습니다.
// Promise 체인 버전
function getCommentsByUser(userId) {
return fetchData(`https://api.example.com/users/${userId}`)
.then(user => {
return fetchData(`https://api.example.com/users/${user.id}/posts`);
})
.then(posts => {
return fetchData(`https://api.example.com/posts/${posts[0].id}/comments`);
});
}
// async/await 버전
async function getCommentsByUser(userId) {
try {
const user = await fetchData(`https://api.example.com/users/${userId}`);
const posts = await fetchData(`https://api.example.com/users/${user.id}/posts`);
const comments = await fetchData(`https://api.example.com/posts/${posts[0].id}/comments`);
return comments;
} catch (error) {
console.error('댓글 가져오기 오류:', error);
throw error;
}
}
비동기 작업의 병렬 처리
여러 비동기 작업을 병렬로 처리하여 성능을 향상시킬 수 있습니다.
// 순차 처리 (더 느림)
async function sequentialFetch() {
console.time('순차 처리');
const user = await fetchData('https://api.example.com/user');
const posts = await fetchData('https://api.example.com/posts');
const comments = await fetchData('https://api.example.com/comments');
console.timeEnd('순차 처리');
return { user, posts, comments };
}
// 병렬 처리 (더 빠름)
async function parallelFetch() {
console.time('병렬 처리');
// 모든 요청을 동시에 시작
const userPromise = fetchData('https://api.example.com/user');
const postsPromise = fetchData('https://api.example.com/posts');
const commentsPromise = fetchData('https://api.example.com/comments');
// 결과를 기다림
const user = await userPromise;
const posts = await postsPromise;
const comments = await commentsPromise;
console.timeEnd('병렬 처리');
return { user, posts, comments };
}
// Promise.all을 사용한 병렬 처리 (더 간결)
async function parallelFetchWithPromiseAll() {
console.time('Promise.all 병렬 처리');
const [user, posts, comments] = await Promise.all([
fetchData('https://api.example.com/user'),
fetchData('https://api.example.com/posts'),
fetchData('https://api.example.com/comments')
]);
console.timeEnd('Promise.all 병렬 처리');
return { user, posts, comments };
}
async/await 에러 처리
try/catch 블록을 사용하여 비동기 코드의 오류를 동기 코드와 유사한 방식으로 처리할 수 있습니다.
// 개별 try/catch
async function fetchAndProcessData() {
try {
const data = await fetchData('https://api.example.com/data');
console.log('데이터:', data);
try {
const processedData = await processData(data);
console.log('처리된 데이터:', processedData);
return processedData;
} catch (processingError) {
console.error('데이터 처리 오류:', processingError);
// 기본 처리 결과 반환
return { processed: false, data };
}
} catch (fetchError) {
console.error('데이터 가져오기 오류:', fetchError);
// 기본 데이터 반환
return { error: true, message: fetchError.message };
}
}
// 대역 try/catch와 오류 종류 구분
async function handleUserData(userId) {
try {
const user = await fetchUser(userId);
const posts = await fetchUserPosts(userId);
return {
user,
posts,
status: 'success'
};
} catch (error) {
// 오류 종류에 따른 처리
if (error.name === 'NetworkError') {
console.error('네트워크 오류:', error);
// 재시도 로직
} else if (error.name === 'ValidationError') {
console.error('유효성 검사 오류:', error);
// 입력 정정 요청
} else {
console.error('알 수 없는 오류:', error);
}
return {
error: true,
message: error.message,
status: 'error'
};
}
}
async/await의 한계와 주의사항
async/await을 사용할 때 알아두어야 할 몇 가지 주의사항이 있습니다.
// 1. 최상위 레벨에서 await 사용 불가 (일부 최신 환경 제외)
// await fetch('https://api.example.com/data'); // 오류 발생
// 즉시 실행 비동기 함수로 해결
(async () => {
const data = await fetch('https://api.example.com/data');
console.log(data);
})();
// 2. forEach와 await 사용 시 주의
async function processItems(items) {
// 잘못된 사용: forEach는 await를 적절히 처리하지 않음
items.forEach(async (item) => {
const result = await processItem(item); // 병렬로 실행됨
console.log(result);
});
console.log('모든 항목 처리 완료'); // 실제로는 처리가 완료되기 전에 실행됨
}
// 올바른 사용: for...of 또는 Promise.all
async function processItemsCorrectly(items) {
// 순차 처리
for (const item of items) {
const result = await processItem(item);
console.log(result);
}
console.log('모든 항목 순차 처리 완료');
// 병렬 처리
const results = await Promise.all(items.map(item => processItem(item)));
console.log(results);
console.log('모든 항목 병렬 처리 완료');
}
'Web Development > JavaScript' 카테고리의 다른 글
| 모듈 시스템 (0) | 2025.03.30 |
|---|---|
| 실전 비동기 프로그래밍 패턴 (0) | 2025.03.30 |
| Promise (0) | 2025.03.30 |
| 콜백 함수 (0) | 2025.03.30 |
| 비동기 프로그래밍 (0) | 2025.03.30 |