## Async와 Await, 비동기 코드를 깔끔하게!
## 미션
비동기 코드를 더 간략하게 하기 위해, async와 await의 사용법을 익히시오.
## 개념
우리는 앞서, 콜백 지옥의 더러운 코드를
프로미스 체이닝으로 개선해보았다.
하지만, 여전히 더럽다는 게 함정..!
### 프로미스 체이닝의 불편함
프로미스 체이닝도 거부한다!
영 맘에 들지 않았던 개발자들.
```
// 사과를 반환하는 프로미스
function applePromise() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("🍎");
}, 1000);
});
}
// 사과 3개를 먹는 프로미스 체이닝
function eatThreeApples() {
applePromise()
.then((apple) => {
console.log(`${apple} 마시따~`);
return applePromise();
})
.then((apple) => {
console.log(`${apple} 마시따~`);
return applePromise();
})
.then((apple) => {
console.log(`${apple} 마시따~`);
console.log("== 잘 먹었습니다 == ");
});
}
```
새로운 문법을 만들게 되는데..
그렇게 "async"와 "await"가 등장하였다.
### async와 await 개요
`async`란,
함수를 비동기 함수로 선언하는 키워드다.
이렇게 선언된 함수는
그 내부에서 await를 사용할 수 있다.
`await`는 비동기 처리 결과를 기다리게 한다.
이들을 사용하면, 위쪽에 작성된
더러운 프로미스 체이닝을
다음과 같이 작성할 수 있다.
```
// 프로미스 체이닝을 async-await로 개선..!
async function eatThreeApplesAsync() {
const apple0 = await applePromise();
console.log(`${apple0} 마시따~`);
const apple1 = await applePromise();
console.log(`${apple1} 마시따~`);
const apple2 = await applePromise();
console.log(`${apple2} 마시따~`);
console.log("== 잘 먹었습니다 == ");
}
```
훨씬 깔끔해 졌다.
딱 봐도 뭐를 써야 할지 감이 오쥬?
그럼 실습을 통해,
구체적인 사용법을 훈련해보자.
## 실습
### 02:10 기본파일 작성
async-await.html
```
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>async-await</title>
<!-- custom -->
<link rel="stylesheet" href="async-await.css">
<!-- bootstrap 5.2 -->
<link href="https://cdn.jsdelivr.net/npm/
[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<Script defer src="https://cdn.jsdelivr.net/npm/
[email protected]/dist/js/bootstrap.bundle.min.js"></Script>
</head>
<body class="container">
<h1 id="heading">async - await</h1>
<article id="practice-1">
<h2>프로미스 객체 vs Async 함수</h2>
<p>프로미스 반환 함수와 async 함수의 공통첨과 차이점, 무엇?</p>
</article>
<article id="practice-2">
<h2>await 사용법</h2>
<p>async 함수에서, 비동기 처리를 기다리는 법!</p>
</article>
<article id="practice-3">
<h2>try-catch-finally 구문</h2>
<p>예외를 처리하는 또 다른 방법!</p>
</article>
</body>
</html>
```
async-await.css
```
/*
* CSS 관련 구글링
* 👉 site:developer.mozilla.org {연관_키워드}
*/
body {
padding-top: 1rem;
}
article {
padding-top: 1rem;
padding-bottom: 1rem;
}
```
async-await.js
```
// JavaScript 관련 구글링
// 👉 site:developer.mozilla.org {연관_키워드}
'use strict';
```
### 03:13 async 무엇? 개념 및 사용법
```
// 1. async 란
// - 비동기 처리를 위한 문법
// - 특정 함수가 Promise를 반환하게 함
// - 기존 프로미스보다 더 간결한, 직관적인 코드 작성가능
// 비동기 함수, Proimse 활용(군더더기가 많은 코드)
function myPromise() {
return new Promise((resolve, reject) => {
resolve("🍎");
});
}
console.log(myPromise());
// 비동기 함수, async 활용(담백한 코드로 개선)
async function myAsync() {
return "🍎"
}
console.log(myAsync());
```
### 06:00 await 사용법
```
// 2. await 란
// - 비동기 처리 결과를 기다리게 함
// - async 함수 내부에서만 사용 가능
// - 프로미스 체이닝을 간결하게 개선(가독성 증가)
// 비동기 함수
function carrotPromise() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("🥕");
}, 1000);
});
}
// 요리하기: 당근 => 스프
// 👉 더 깔끔한 코드는 없을까..?
// 👉 async와 await로 코드를 개선
async function cookCarrotSoup() {
// await로,
// 프로미스 작업을 기다릴 수 있음
// resolve의 전달 값을 간단히 받을 수 있음
const carrot = await carrotPromise();
console.log(`[${carrot}] 스프를 만들었어요`);
}
cookCarrotSoup();
```
### 09:55 예외 처리하기: try-catch-finally 문
프로미스 코드 변경
```
// 비동기 함수
function carrotPromise() {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() < 0.5) {
resolve("🥕");
} else {
reject("🍉");
}
}, 1000);
});
}
```
예외 처리 구문 추가
```
// 요리하기: 당근 => 스프
// 👉 더 깔끔한 코드는 없을까..?
// 👉 async와 await로 코드를 개선
async function cookCarrotSoup() {
try {
// try 블럭: 정상 수행하길 바라는 코드
const carrot = await carrotPromise();
console.log(`[${carrot}] 스프를 만들었어요`);
} catch (error) {
// catch 블럭: 에러 발생시 처리할 코드
console.log(`요리 실패: ${error}으로 스프를? 멈춰!`);
} finally {
// finally 블럭: 무조건 수행할 코드
console.log("== 끝! ==");
}
}
cookCarrotSoup();
```
### 12:41 async 함수의 반환값
```
// 요리하기: 당근 => 스프
// 👉 프로미스긴 한데, 더 깔끔한 코드 없을까?
// 👉 프로미스 호출을 async와 await로 개선!
async function cookCarrotSoup() {
try {
// try 블럭: 정상 수행하길 바라는 코드
const carrot = await carrotPromise();
console.log(`[${carrot}] 스프를 만들었어요`);
return "당근 스프"; // resolve("당근 스프");
} catch (error) {
// catch 블럭: 에러 발생시 처리할 코드
console.log(`요리 실패: ${error}으로 스프를? 멈춰!`);
throw new Error("요리 실패"); // reject("요리 실패");
} finally {
// finally 블럭: 무조건 수행할 코드
console.log("== 끝! ==");
}
}
// 체이닝 가능? Yes. async 함수가 프로미스를 반환하므로
cookCarrotSoup()
.then((data) => { console.log(data) })
.catch((err) => { console.log(err) })
.finally(() => { console.log("== 진짜 끝!! ==") });
```
## 구글링 훈련 🔥
- 자바스크립트 async await
- 자바스크립트 예외 처리
- 자바스크립트 try catch finally
- 자바스크립트 에러 객체