
2025 / 02 / 18
오늘 수업 시간에는 async / await의 사용과 try - catch문의 사용 방법을 배웠습니다.
기존에 fetch함수와 then( )을 사용할 때와는 다르게 내용이 확 와닿지는 않습니다..
C# 세미나를 했을 때 내용 발표를 해본 경험이 있어서 개념 자체는 어렵진 않았습니다.
- Async와 Await는 비동기 처리 코드를 더 간단하고 직관적으로 작성할 수 있게 해주는 JavaScript의 키워드입니다.
- Promise 기반으로 동작하지만, then( ) 메서드나 .catch( )와 같은 방식보다 코드를 더 간결하고 가독성 있게 만들어 줍니다.
- async 키워드는 함수 앞에 사용되며, 해당 함수가 Promise를 반환하도록 합니다.
- async 함수는 항상 Promise를 반환하므로, 반환값을 처리하기 위해서는 .then( ) 또는 await를 사용할 수 있습니다.
async function example() {
return "Hello, World!";
}
example().then(result => console.log(result)); // "Hello, World!"
- await 키워드는 async 함수 안에서만 사용할 수 있습니다.
- await는 Promise가 처리될 때까지 기다리며, Promise가 해결되면 그 값을 반환합니다.
- await를 사용하면 Promise의 결과를 바로 받을 수 있어서 코드가 동기식처럼 작성됩니다.
async function fetchData() {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
return data;
}
- 자바스크립트에서 에러를 처리하는 방법으로 try-catch 문을 사용할 수 있습니다.
- 코드 실행 중에 발생할 수 있는 예외 상황을 처리하기 위해 사용됩니다.
try 블록- 실행할 코드를 작성합니다.catch 블록- try 블록에서 에러가 발생하면 이 곳에서 처리합니다.finally 블록- 에러 여부와 상관없이 항상 실행됩니다.
try {
const result = riskyFunction();
} catch (error) {
console.log("에러 발생: ", error);
} finally {
console.log("무조건 실행");
}
- Async / Await와 Try-Catch를 결합하면 비동기 코드에서 발생할 수 있는 에러를 효과적으로 처리할 수 있습니다.
- 비동기 함수 내에서 발생할 수 있는 에러를 catch로 잡을 수 있어 더 안정적인 코드를 작성할 수 있습니다.
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
return data;
} catch (error) {
console.log("에러 발생: ", error);
} finally {
console.log("데이터 fetching 완료");
}
}
- fetch와 async/await를 사용한 비동기 처리 방식을 비교해보았습니다.
- fetch를 사용해서 데이터를 받아올 때, then( ) 방식은 Promise의
.then( )을 사용하여 비동기 처리를 합니다.fetch("https://jsonplaceholder.typicode.com/posts/2") .then((response) => response.json()) // 첫 번째 then()에서 response를 json으로 파싱 .then((json) => console.log(json)) // 두 번째 then()에서 json 데이터 출력 .catch((error) => console.log("오류 발생", error)); // 에러 처리
첫 번째 then( )
두 번째 then( )
catch( )
- await를 사용하여 비동기적인 fetch 요청을 더 직관적으로 처리합니다.
- 코드가 동기식처럼 보이게 만들어 가독성을 높입니다.
async function runner(num) { try { // fetch에 대한 성공 값으로 Response 객체를 반환한다. const response = await fetch( `https://jsonplaceholder.typicode.com/posts/${num}` ); // json()에 대한 성공 값으로 자바스크립트 객체를 반환한다. const data = await response.json(); console.log(data); } catch (error) { console.log("오류 발생", error); // 에러가 발생하면 이곳에서 처리 } } // 받아오고 싶은 값을 넘겨준다. // fetch url에 백틱을 사용하여 해당 인수를 넘겨준다. runner(3);
async
await
await response.json( )
try-catch
then( ) 방식과 async/await 방식은 비동기 코드 처리에서 같은 결과를 얻지만, 구조와 가독성에서 차이가 있습니다.
| 구분 | then( ) 사용 | async/await 사용 |
|---|---|---|
| 비동기 흐름 | .then( )으로 비동기 흐름을 처리하고, 체이닝 방식으로 진행 | await로 비동기 흐름을 직관적으로 처리 |
| 에러 처리 | .catch( )를 사용하여 에러를 처리 | try-catch를 사용하여 에러를 처리 |
| 코드 가독성 | 여러 줄로 나누어져 코드가 길어지며 가독성이 떨어질 수 있음 | 코드가 동기식처럼 보이며, 더 간결하고 가독성이 좋음 |
| 코드 흐름 | 여러 .then( ) 호출로 비동기적인 코드 흐름이 이어짐 | await를 사용하여 동기식처럼 코드 흐름이 자연스럽게 작성됨 |
then( ) 사용
- 각 .then( )과 .catch( )로 코드가 나누어져 있습니다.
- 여러 단계로 나뉘어있는 비동기 처리가 코드에서 눈에 띄게 드러납니다.
- 비동기 흐름이 체이닝 형태로 이어집니다.
async/await 사용
- await를 사용하여 Promise의 결과를 기다리는 방식으로 코드가 직관적이고 동기식처럼 보입니다.
- try-catch로 에러 처리를 통합적으로 할 수 있어서 코드가 깔끔해집니다.
- 가독성이 뛰어나며 에러 처리가 더 명확하고 코드 흐름을 쉽게 따라갈 수 있습니다.
fetch를 사용하여 API에서 사용자 데이터를 받아오고 사용하기
- 사용할 변수를 초기화합니다.
- Api를 호출해 데이터를 받아오는 함수를 정의합니다.
- 해당 함수를 호출 후 버튼 클릭 시 새로운 사용자의 데이터를 로드합니다.
사용할 변수를 초기화합니다.
- HTML DOM을 사용해서 해당 태그에 접근합니다.
- 태그에 접근한 내용은 각각의 변수에 담습니다.
const user_image = document.getElementById("user-image"); const user_name = document.getElementById("user-name"); const user_email = document.getElementById("user-email"); const user_location = document.getElementById("user-location"); const load_btn = document.getElementById("load-user");
Api를 호출해 데이터를 받아오는 함수를 정의합니다.
- fetchRandomUser 함수는 사용자의 데이터를 가져오기 위한 함수입니다.
- fetch API를 사용하여 외부에서 데이터를 요청하고, 응답받은 데이터를 HTML 요소에 표시합니다.
const fetchRandomUser = () => { fetch("https://randomuser.me/api/") // API 호출 .then((response) => { if (response.ok) { return response.json(); // 응답이 정상일 경우 JSON 데이터로 파싱 } }) .then((data) => { // 데이터 처리 부분 const [user] = data.results; // 첫 번째 사용자 데이터를 추출 // 사용자 데이터 표시 user_image.src = user.picture.large; // 사용자 이미지 출력 user_name.innerHTML = `${user.name.first} ${user.name.last}`; // 이름 출력 user_email.innerHTML = user.email; // 이메일 출력 user_location.innerHTML = user.location.country; // 위치 출력 }) .catch((error) => { console.error("데이터 전송에 실패했습니다.", error); // 오류 처리 }); };
fetch("https://randomuser.me/api/")
.then((response) => {...})
return response.json( )
.then((data) => {...})
const [user] = data.results;
user_image.src = user.picture.large;
user_name.innerHTML = ...:
user_email.innerHTML = user.email;
user_location.innerHTML = user.location.country;
.catch((error) => {...})
해당 함수를 호출 후 버튼 클릭 시 새로운 사용자의 데이터를 로드합니다.
- 스크립트가 로드될 때 한 번 호출하여 처음 사용자 데이터를 로드합니다.
- 버튼을 클릭하면 fetchRandomUser( ) 함수가 호출되어 새로운 사용자 데이터를 불러옵니다.
fetchRandomUser();<button id="load-user" class="load-user-btn" onclick="fetchRandomUser()">Load New User</button>
1. 페이지 로드 시
- fetchRandomUser() 함수가 호출되어 첫 번째 사용자 데이터를 API에서 받아옵니다.
2. 버튼 클릭 시
- 사용자가 "Load New User" 버튼을 클릭하면, fetchRandomUser() 함수가 다시 호출되어 새로운 사용자 데이터를 API에서 받아옵니다.
3. API 응답
- API에서 받은 데이터를 처리하여 사용자 정보(이름, 이메일, 위치, 이미지 등)를 화면에 출력합니다.
4. 에러 처리
- 만약 API 호출이나 데이터 처리 중에 오류가 발생하면, catch에서 이를 처리하고 오류 메시지를 콘솔에 출력합니다.
- 위에서 스크립트 코드만 설명을 하고 있는데, 아래 코드는 HTML과 CSS를 포함한 코드입니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Random User Profile</title>
<style>
body {
background-color: #f4f4f4;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.user-card {
background: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
text-align: center;
width: 300px;
}
.user-avatar {
width: 100px;
height: 100px;
border-radius: 50%;
margin-bottom: 15px;
}
.user-name {
font-size: 20px;
font-weight: bold;
margin-bottom: 5px;
}
.user-email {
font-size: 14px;
color: #555;
margin-bottom: 10px;
}
.user-location {
font-size: 16px;
color: #333;
margin-bottom: 15px;
}
.load-user-btn {
background-color: #007bff;
color: white;
border: none;
padding: 10px 15px;
border-radius: 5px;
cursor: pointer;
}
.load-user-btn:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<div id="user-card" class="user-card">
<img id="user-image" src="" alt="User Avatar" class="user-avatar" />
<h2 id="user-name" class="user-name"></h2>
<p id="user-email" class="user-email"></p>
<p id="user-location" class="user-location"></p>
<button id="load-user" class="load-user-btn" onclick="fetchRandomUser()">
Load New User
</button>
</div>
<script>
// api를 요청하여 받은 데이터를 넣을 요소 가져오기
const user_image = document.getElementById("user-image");
const user_name = document.getElementById("user-name");
const user_email = document.getElementById("user-email");
const user_location = document.getElementById("user-location");
const load_btn = document.getElementById("load-user");
// 데이터 요청 함수
const fetchRandomUser = () => {
fetch("https://randomuser.me/api/")
.then((response) => {
if (response.ok) {
return response.json();
}
})
.then((data) => {
// 구조분해를 사용하여 변수에 넣기
const [user] = data.results;
console.log(user);
// user.picture.large에 있는 사진을 user_image의 src 속성에 넣기
user_image.src = user.picture.large;
const name = `${user.name.first} ${user.name.last}`;
user_name.innerHTML = name;
const email = user.email;
user_email.innerHTML = email;
const location = user.location.country;
user_location.innerHTML = location;
})
.catch((error) => {
console.error("데이터 전송에 실패했습니다.", error);
});
};
fetchRandomUser();
</script>
</body>
</html>
30일차 후기
- fetch 함수와 Promise 객체에 익숙해지기 전에 async/await를 배워서 헷갈렸습니다.
- API로부터 데이터를 받아오고, 해당 데이터를 사용해보는 것까지 실습을 하면서... "앞으로의 프로젝트에는 많은 API가 쓰이겠지"라는 생각이 들어서 더 걱정입니다.
- 생각만 하고 보니 막막하기도 해서 개념을 확실히 이해하고 넘어가야할 것 같습니다.
- 아니 근데 왜 자꾸 실습하는데 async가 오타가 나는 걸까요.. 진짜 의문입니다..
- DOM 요소에 동적으로 반영하는 것은 어느정도 익숙해진 것 같습니다. ‹( '▿' )›
- 하루 수업 진도가 적은 편은 아닌 것 같아서 복습을 꾸준히 해야겠습니다. ૮(ॢ ᵕㅅᵕ ॢ )ა