1. 오늘의 학습 목표
학습 목표: 프로미스를 기반으로 비동기 코드를 마치 동기 코드처럼 간결하고 직관적으로 작성할 수 있게 해주는 async 함수와 await 연산자의 사용법을 배웁니다. try...catch 구문을 이용한 효과적인 비동기 에러 핸들링 방법을 익힙니다.
핵심 요약: async/await는 복잡한 .then() 체이닝을 대체하여 비동기 코드의 가독성을 혁신적으로 높여주는 현대 JavaScript의 표준 문법입니다.
2. 핵심 개념 파헤치기
2.1. async 함수
함수 선언 앞에 async 키워드를 붙이면, 해당 함수는 항상 프로미스를 반환하는 비동기 함수가 됩니다.
- 만약 함수가 값을 반환하면, 그 값으로 이행(resolve)되는 프로미스가 반환됩니다.
- 만약 함수 내부에서 에러가 발생하면, 그 에러를 담아 거부(reject)되는 프로미스가 반환됩니다.
async function myFunction() { return 'hello'; } myFunction().then(console.log); //'hello'
2.2. await 연산자
await 연산자는 async 함수 안에서만 사용할 수 있으며, 프로미스가 처리(settled)될 때까지 함수의 실행을 일시 정지시킵니다. 프로미스가 이행되면, await는 그 결과값을 반환하고, 거부되면 에러를 던집니다
비동기 작업의 결과를 변수에 바로 할당받는 등 마치 동기적인 코드처럼 작성할 수 있습니다.
const result = await somePromiseFunction();
2.3. 에러 핸들링 (Error Handling) with try...catch
async/await 구문의 가장 큰 장점 중 하나는 동기 코드에서 사용하던 try...catch 문으로 비동기 코드의 에러를 처리할 수 있다는 점입니다. 프로미스의 .catch() 체인보다 훨씬 더 익숙하고 직관적인 방법으로 에러를 관리할 수 있습니다.
try { const result = await mightFailFunction(); } catch (error) { console.error(error); }
3. 코드로 배우기
3.1. 구현 목표
Day 16에서 프로미스 체이닝으로 작성했던 순차적 비동기 코드를 async/await를 사용하여 리팩토링합니다.
3.2. [1단계: 프로미스를 반환하는 함수 준비]
Day 16에서 사용했던 delay 함수를 그대로 사용합니다. await는 프로미스를 기다리는 연산자이므로, 프로미스를 반환하는 함수가 필요합니다.
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
3.3. [2단계: async 함수 안에서 await 사용하기]
async 키워드를 붙인 runTasks 함수를 만들고, 그 안에서 await를 사용하여 delay 함수를 순차적으로 호출합니다. 코드가 .then() 없이 간단한 동기 코드처럼 보입니다.
async function runTasks() {
await delay(1000);
console.log(1);
await delay(1000);
console.log(2);
await delay(1000);
console.log(3);
}
runTasks();
3.4. [3단계: try...catch로 에러 처리하기]
에러가 발생할 가능성이 있는 코드를 try 블록으로 감싸고, 에러 발생 시 처리할 로직을 catch 블록에 작성합니다.
function riskyDelay(ms) {
return new Promise((resolve, reject) => {
if (Math.random() > 0.5) {
setTimeout(resolve, ms);
} else {
reject(new Error('랜덤 에러 발생!'));
}
});
}
async function runRiskyTasks() {
try {
await riskyDelay(1000);
console.log('1초 후 실행 (성공)');
await riskyDelay(1000);
console.log('2초 후 실행 (성공)');
} catch (error) {
console.error('작업 중단:', error.message);
} finally {
console.log('위험한 작업 시도 완료');
}
}
runRiskyTasks();
4. 전체 코드
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>JS Async/Await</title>
</head>
<body>
<h1>F12를 눌러 개발자 도구 콘솔을 확인하세요.</h1>
<script>
console.log("--- async/await으로 비동기 처리하기 ---");
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
//async/await를 사용한 함수
async function process() {
try {
console.log('작업 시작...');
await delay(1000);
console.log('1초 경과');
await delay(1000);
console.log('2초 경과');
//await Promise.reject('의도적인 에러'); //에러 테스트
await delay(1000);
console.log('3초 경과. 작업 완료!');
return '성공'; //이 값은 process() 프로미스의 결과값이 됩니다.
} catch (error) {
console.error('에러 발생:', error);
return '실패';
}
}
//async 함수는 프로미스를 반환하므로 .then으로 결과를 받을 수 있습니다.
process().then(result => {
console.log('최종 결과:', result);
});
</script>
</body>
</html>'개발 > 웹 개발' 카테고리의 다른 글
| Day 19: 컴포넌트 기반 아키텍처 (CBA) (2) | 2024.08.22 |
|---|---|
| Day 18: ES6+ 필수 문법 (0) | 2024.08.21 |
| Day 16: JavaScript 비동기 (콜백과 프로미스) (0) | 2024.08.18 |
| Day 15: JavaScript와 DOM (2) | 2024.08.14 |
| Day 14: JavaScript 객체와 배열 (1) | 2024.08.14 |