React

프로미스를 async await으로 바꾸기

hihiha2 2023. 4. 24. 14:47

🤔 Promise사용 코드

useEffect(() => {
getBookData()
.then((res) => setPosts(res.data.items))
.catch((err) => console.log(err));
}, []);

 

✅ async await으로 바꾼 코드

const getApi = async () => {
try {
const response = await getBookData();
const { data } = response;
setPosts(data.items);
} catch (e) {
console.error(e);
}
};
 
 
useEffect(() => {
getApi();
}, []);

 

 

💻 async/await 구문을 사용하여 getBookData()함수 호출

1️⃣ const response = await getBookData();

getBookData 함수를 호출한 결과를 저장하기 위해 response라는 변수를 선언한다.

getBookData함수가 프로미스 객체를 반환하기 때문에, 이 프로미스 객체를 await를 사용하여 비동기처리

 

2️⃣ const { data } = response;

 response.data에서 API응답 데이터를 가져오기 위해 객체분해할당 사용

 

3️⃣ try-catch문

에러처리를 위해 사용

 

4️⃣ useEffect훅

컴포넌트가 처음  렌더링될때, getApi함수를 실행시켜서 API로부터 데이터를 가져와서 상태값을 업데이트하는 효과

두번째 매개변수로 빈배열을 전달, 컴포넌트가 처음 마운트될때만 실행되도록 함

 

 

👍 async/await으로 바꾼 이유 = 장점 👍 

Promise 기반으로 한 비동기처리 패턴을 보다 간결하게 사용

 

1. 코드의 가독성

async/await을 사용하면 promise를 사용할때와 달리 콜백함수를 작성하지 않고도 비동기처리를 동기식으로 작성할 수 있어 코드의 가독성을 높인다.

 

2. 보다 쉬운 오류처리

try/catch 구문을 사용

promise의 then()메서드 체이닝 구문을 대체할수 있어서 코드의 가독성 ⬆️

(대신 모든 오류를 try/catch구문으로 처리해주어야한다)

 

 

 

💻 전체코드

import { useState, useEffect } from "react";
import { getBookData } from "../../API/Api.js";
import BookCard from "../BookCard/BookCard.js";
import Pagination from "../Pagination/Pagination.js";


export default function Posts({
  bookData,
  selectedBook,
  setSelectedBook,
  BookDetailModal,
  handleCloseBookDetailModal,
}) {
  const [posts, setPosts] = useState([]);
  const limit = 8;
  const [page, setPage] = useState(1);
  const offset = (page - 1) * limit;

  const formattedData = bookData
    ?.filter(
      (item) =>
        item.volumeInfo?.imageLinks?.smallThumbnail &&
        item.volumeInfo?.title &&
        item.saleInfo?.listPrice?.amount
    )
    .slice(offset, offset + limit);

  const getApi = async () => {
    try {
      const response = await getBookData();
      const { data } = response;
      setPosts(data.items);
    } catch (e) {
      console.error(e);
    }
  };

  useEffect(() => {
    getApi();
  }, []);

  return (
      <main>
        <div className="container">
          {formattedData.map((books) => {
            return (
              <BookCard
                key={books.id}
                books={books}
                setSelectedBook={setSelectedBook}
              />
            );
          })}
          {selectedBook && (
            <BookDetailModal
              selectedBook={selectedBook}
              onClose={handleCloseBookDetailModal}
            />
          )}
        </div>
      </main>

      <footer>
        <Pagination
          total={posts.length}
          limit={limit}
          page={page}
          setPage={setPage}
        />
      </footer>
    </div>
  );
}

 

 

🤔 Promise사용 코드 2

const handleSubmitSearch = () => {
getBookData(search, selected).then((res) => {
console.log("res ===>>>>", res);
setBookData(res.data.items);
});
};

 

✅ async await으로 바꾼 코드 2

const handleSubmitSearch = async () => {
try {
const response = await getBookData(search, selected);
console.log("res ===>>>>", response);
setBookData(response.data.items);
} catch (error) {
console.error(error);
}
};

 

또다른 예시

// Promise를 사용한 비동기 처리
function getData() {
  return axios.get('/api/data')
    .then(response => response.data)
    .catch(error => console.error(error));
}

// async/await를 사용한 비동기 처리
async function getData() {
  try {
    const response = await axios.get('/api/data');
    return response.data;
  } catch (error) {
    console.error(error);
  }
}