본문 바로가기
카테고리 없음

promise 대신 async await을 사용한 fetch

by cariño 2024. 11. 22.
728x90
반응형

1. 기본 사용법

async function fetchData(url) {
    try {
        const response = await fetch(url); // HTTP 요청 보내기
        if (!response.ok) { // 응답 상태 확인
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        const data = await response.json(); // JSON 데이터 파싱
        return data; // 데이터 반환
    } catch (error) {
        console.error('Error fetching data:', error);
    }
}

// 사용 예시
fetchData('https://api.example.com/data')
    .then(data => console.log(data));

POST 요청 보내기

데이터를 서버에 보낼 때는 fetch의 두 번째 매개변수로 요청 옵션을 설정한다.

async function postData(url, payload) {
    try {
        const response = await fetch(url, {
            method: 'POST', // HTTP 메서드 설정
            headers: {
                'Content-Type': 'application/json', // 요청 헤더 설정
            },
            body: JSON.stringify(payload), // 요청 본문 설정
        });
        
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        const result = await response.json(); // JSON 응답 처리
        return result;
    } catch (error) {
        console.error('Error posting data:', error);
    }
}

// 사용 예시
postData('https://api.example.com/create', { name: '이름', age: 30 })
    .then(result => console.log(result));

 

예외 처리와 로딩 상태 표시

로딩 상태를 표시하거나 예외를 처리하려면 추가 논리를 구현

async function fetchWithLoading(url) {
    console.log('Loading...'); // 로딩 시작
    try {
        const response = await fetch(url);
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        const data = await response.json();
        console.log('Data fetched successfully!');
        return data;
    } catch (error) {
        console.error('Error:', error);
    } finally {
        console.log('Loading finished.'); // 로딩 종료
    }
}

// 사용 예시
fetchWithLoading('https://api.example.com/data')
    .then(data => console.log(data));

 

실제 사례

REST API에서 데이터를 가져와 화면에 출력하는 경우:

async function loadUsers() {
    const url = 'https://jsonplaceholder.typicode.com/users';
    try {
        const users = await fetchData(url);
        users.forEach(user => {
            console.log(`Name: ${user.name}, Email: ${user.email}`);
        });
    } catch (error) {
        console.error('Error loading users:', error);
    }
}

loadUsers();

 

기본 공통 fetch 함수

 

async function request(url, options = {}) {
    try {
        const defaultOptions = {
            headers: {
                'Content-Type': 'application/json',
            },
        };

        // 옵션 병합
        const config = { ...defaultOptions, ...options };

        const response = await fetch(url, config);
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        return await response.json();
    } catch (error) {
        console.error('Fetch error:', error);
        throw error; // 호출하는 쪽에서 에러를 처리할 수 있도록 전달
    }
}

GET 요청 함수

GET 요청의 경우 별도의 옵션 없이 사용할 수 있다.

async function get(url) {
    return await request(url, {
        method: 'GET',
    });
}

POST 요청 함수

POST 요청에 데이터를 함께 보낼 수 있도록 구현

async function post(url, data) {
    return await request(url, {
        method: 'POST',
        body: JSON.stringify(data),
    });
}

PUT 및 DELETE 요청 함수

다른 HTTP 메서드에 대해서도 확장 가능

async function put(url, data) {
    return await request(url, {
        method: 'PUT',
        body: JSON.stringify(data),
    });
}

async function del(url) {
    return await request(url, {
        method: 'DELETE',
    });
}

 

사용 예시

 

async function fetchExample() {
    try {
        // GET 요청
        const getData = await get('https://jsonplaceholder.typicode.com/posts');
        console.log('GET data:', getData);

        // POST 요청
        const postData = await post('https://jsonplaceholder.typicode.com/posts', {
            title: 'foo',
            body: 'bar',
            userId: 1,
        });
        console.log('POST data:', postData);

        // PUT 요청
        const putData = await put('https://jsonplaceholder.typicode.com/posts/1', {
            id: 1,
            title: 'updated title',
            body: 'updated body',
            userId: 1,
        });
        console.log('PUT data:', putData);

        // DELETE 요청
        const deleteData = await del('https://jsonplaceholder.typicode.com/posts/1');
        console.log('DELETE response:', deleteData);
    } catch (error) {
        console.error('Error during API calls:', error);
    }
}

fetchExample();

 

추가 기능 (옵션 및 타임아웃 추가)

타임아웃을 적용하려면 Promise.race를 사용할 수 있다.

 

async function requestWithTimeout(url, options = {}, timeout = 5000) {
    const fetchPromise = request(url, options);
    const timeoutPromise = new Promise((_, reject) =>
        setTimeout(() => reject(new Error('Request timed out')), timeout)
    );
    return Promise.race([fetchPromise, timeoutPromise]);
}

// 사용 예시
async function fetchWithTimeoutExample() {
    try {
        const data = await requestWithTimeout('https://jsonplaceholder.typicode.com/posts', {}, 3000);
        console.log('Data fetched:', data);
    } catch (error) {
        console.error('Error with timeout:', error);
    }
}

fetchWithTimeoutExample();
728x90

댓글