Async/Await에 대해

oversleep·2025년 2월 3일
post-thumbnail

Async/Await는:

JavaScript에서 비동기 작업을 더 쉽고 읽기 쉽게 처리할 수 있게 해주는 문법.

async 함수:

  • async 키워드를 함수 앞에 붙여서 정의함.
  • 이 함수는 항상 Promise를 반환함.
  • async 함수 내에서 await 키워드를 사용하여 비동기 작업이 완료될 때까지 기다릴 수 있음.

await 표현식:

  • await 키워드를 사용하여 비동기 작업이 완료될 때까지 기다림
  • 이때 awaitasync 함수 내에서만 사용될 수 있음.
  • await 키워드 뒤에는 Promise를 반환하는 비동기 작업이 옴.
  • await는 이 작업이 완료될 때까지 해당 코드 블록의 실행을 일시 중단하고, 작업이 완료되면 결과 값을 반환함.
  1. 기본 문법:
async function getData() {
    try {
        const response = await fetch('https://api.example.com/data');
        const data = await response.json();
        console.log(data);
    } catch (error) {
        console.error('에러 발생:', error);
    }
}
  1. Promise와의 비교:
// Promise 방식
fetch('https://api.example.com/data')
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error(error));

// Async/Await 방식
async function fetchData() {
    try {
        const response = await fetch('https://api.example.com/data');
        const data = await response.json();
        console.log(data);
    } catch (error) {
        console.error(error);
    }
}
  1. 병렬 처리:
// 여러 작업 동시 실행
async function getAllData() {
    try {
        const [users, posts, comments] = await Promise.all([
            fetch('/api/users').then(r => r.json()),
            fetch('/api/posts').then(r => r.json()),
            fetch('/api/comments').then(r => r.json())
        ]);
        
        console.log('사용자:', users);
        console.log('게시물:', posts);
        console.log('댓글:', comments);
    } catch (error) {
        console.error('에러:', error);
    }
}
  1. 실제 활용 예시:
// 로그인 기능 구현
async function login(username, password) {
    try {
        // 로그인 요청
        const loginResponse = await fetch('/api/login', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ username, password })
        });

        if (!loginResponse.ok) {
            throw new Error('로그인 실패');
        }

        // 사용자 정보 가져오기
        const userData = await loginResponse.json();
        
        // 프로필 정보 가져오기
        const profileResponse = await fetch(`/api/profile/${userData.id}`);
        const profileData = await profileResponse.json();

        return {
            user: userData,
            profile: profileData
        };
    } catch (error) {
        console.error('로그인 중 에러:', error);
        throw error; // 상위 컴포넌트에서 처리할 수 있도록 에러 전파
    }
}

// 사용 예시
async function handleLoginButton() {
    try {
        const result = await login('user123', 'password123');
        console.log('로그인 성공:', result);
    } catch (error) {
        alert('로그인에 실패했습니다.');
    }
}
  1. 주의사항과 팁:
  • async 함수는 항상 Promise를 반환
  • await는 async 함수 내에서만 사용할 수 있음
  • 루프에서 await 사용 시 주의가 필요:
// 잘못된 예시 (순차적 실행)
async function fetchUserPosts(userIds) {
    const posts = [];
    for (const id of userIds) {
        const post = await fetch(`/api/posts/${id}`); // 각 요청이 순차적으로 실행됨
        posts.push(await post.json());
    }
    return posts;
}

// 좋은 예시 (병렬 실행)
async function fetchUserPosts(userIds) {
    const promises = userIds.map(id => 
        fetch(`/api/posts/${id}`).then(r => r.json())
    );
    return Promise.all(promises);
}
  1. 에러 처리:
async function fetchData() {
    try {
        const response = await fetch('https://api.example.com/data');
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        const data = await response.json();
        return data;
    } catch (error) {
        if (error.name === 'TypeError') {
            console.error('네트워크 오류:', error);
        } else {
            console.error('기타 오류:', error);
        }
        throw error;
    }
}

요약

Async/Await를 사용하면 비동기 코드를 마치 동기 코드처럼 작성할 수 있어 가독성이 좋음.
에러 처리도 try/catch를 통해 더 직관적으로 할 수 있음.

profile
궁금한 것, 했던 것, 시행착오 그리고 기억하고 싶은 것들을 기록합니다.

0개의 댓글