Async/Await
지금까지 비동기 프로그래밍은 콜백 또는 Promise를 활용해왔습니다. 하지만 ECMAScript2017(ES8+) 부터 새롭게 추가된 Async/Await를 사용하면 비동기 프로그래밍을 보다 직관적으로 관리할 수 있습니다.
Async 함수
함수를 Async 함수로 변경하려면 function
앞에 async
키워드를 붙입니다.
Async 함수는 암묵적으로 Promise를 반환하므로 .then()
또는 .catch()
메서드를
사용해 실행(fulfill), 거절(reject)을 처리할 수 있습니다.
async function asyncFn() {
if ( Math.random() > 0.5 ) {
return '0.5보다 큽니다.';
} else {
return new Error('0.5보다 작습니다!!');
}
}
asyncFn()
.then(response => console.log(response))
.catch(error => console.error(error.message));
Await
await
키워드는 데이터가 응답 반환 될 때까지 실행 흐름을 일시 중단합니다.
아래 코드는 약 2초의 지연된 시간 뒤에 응답하는 getData()
함수를 사용해
비동기 처리를 시뮬레이션 하는 코드입니다. await
는 getData()
함수의
응답이 올 때까지 대기하였다가 응답이 오면 data
에 결과를 할당합니다.
const getData = () => {
let timeout = Math.floor(Math.random() * 2000);
return new Promise(resolve => {
window.setTimeout(() => resolve(['지연', '된', '데이', '터', '전송']), timeout);
});
};
async function asyncFn() {
const data = await getData(); // 데이터 응답까지 대기
console.log(data); // 응답 받은 후 데이터 출력
}
주의!
await
키워드는 Async 함수 내부에서만 사용 가능합니다.
function async() {
// Uncaught SyntaxError: await is only valid in async function
const data = await getData();
console.log(data);
}
코드 비교
Promise와 Async 함수의 코드를 비교해보겠습니다.
Promise 코드
const api = 'https://jsonplaceholder.typicode.com';
function asyncCallDatas() {
let todo, photo;
Promise.all([
fetch(`${api}/todos/9`)
.then(response => response.json())
.then(data => todo = data),
fetch(`${api}/photos/7`)
.then(response => response.json())
.then(data => photo = data)
])
.then(results => console.log(todo, photo));
}
asyncCallDatas();
Async/Await 코드
const api = 'https://jsonplaceholder.typicode.com';
async function asyncCallDatas() {
let todo = await (await fetch(`${api}/todos/9`)).json();
let photo = await (await fetch(`${api}/photos/7`)).json();
console.log(todo, photo);
}
asyncCallDatas();
위 코드는 아래와 같이 Promise.all(), 구조 분해 할당을 활용해 처리할 수도 있습니다.
async function asyncCallDatas() {
let [ todo, photo ] = await Promise.all([
(await fetch(`${api}/todos/9`)).json(),
(await fetch(`${api}/photos/7`)).json()
]);
console.log(todo, photo);
}