
async 와 await는 프로미스 객체를 더욱 쉽게 작성할 수 있고, 직관적으로 코드를 해석할 수 있는 문법이다.
먼저, 프로미스 객체를 사용해 간단한 비동기 처리 함수를 작성해보자.
const delay = (ms) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, ms);
});
};
const start = () => {
delay(2000).then(() => {
console.log('대기');
});
};
start();
delay함수는 setTimeout함수에서 사용될 지연 시간을 매개변수로 받는다.resolve함수를 호출한다.start함수는 이용해 delay함수를 호출한다.start함수는 delay함수의 인수로 2000을 넘겨 2초동안 지연시키고,then메서드를 사용해 '대기'라는 단어를 출력한다.
이제, 위 코드를 async/awiat를 이용해 더 직관적으로 작성해보자.
const start = async () => {
delay(2000).then(() => {
console.log('대기');
});
};
async 키워드는 함수 이름의 오른쪽에 작성된다.

async 키워드가 붙은 함수 start에 마우스를 올려보면 이 함수는 프로미스 객체를 반환한다고 표시되는데, 실제로 이 async 키워드가 붙은 start 함수를 출력해보면 Promise {<pending>}, 즉 state가 pending인 프로미스가 출력되는 것을 볼 수 있다.
이렇게 async를 붙인 함수는 자동으로 프로미스 객체를 반환하는 비동기처리 함수가 되기 때문에, 아래와 같이then메서드를 이용해 start함수를 작성할 수 있다.
const start = async () => {
/*
delay(2000).then(() => {
console.log('대기');
});
*/
return '대기';
};
start().then((res) => {
console.log(res);
});
코드를 실행해보면 '대기'가 출력되는데, 이는 start함수의 반환 값과 start함수가 반환하는 프로미스 객체의 resolve값이 동일하기 때문이다.
await키워드는 특정 함수의 앞에 작성되며, then키워드를 대신하여 사용할 수 있다.
const start = async () => {
await delay(2000);
console.log('대기');
};
await는 async가 붙어있는 함수의 내부에서만 사용이 가능하며, 해당 프로미스가 처리될 때까지 기다린 다음에야 결과값을 받아 볼 수 있다.
따라서, await가 작성된 함수가 종료되기 전에는 그 아래에 작성된 코드들은 수행되지 않는다.
await을 지우고 코드를 실행하면 다음과 같이 '대기'가 바로 출력된다.

반면에 await을 작성하고 코드를 실행하면 다음과 같이 2초후에 '대기'가 출력된다.

이렇게 async와 await으로 비동기 함수를 처리하면 프로미스 객체를 편리하고 가독성있게 사용할 수 있고, 비동기 함수의 실행 순서를 예측할 수 있다.
async와 await을 이용한 비동기 처리 함수에서는 try catch문법을 이용해 예외처리를 할 수 있다.
const delay = (ms) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, ms);
});
};
const start = async () => {
try{
await delay(2000);
console.log('대기');
} catch(error) {
console.log(error);
};
};
start();
try의 블록 안에 작성된 코드가 실행되고 해당 코드에서 에러가 발생한다면, 아래에 작성할 catch블록 안의 코드가 실행되게 된다.
발견된 에러는 이 catch에 전달된 error객체에 담기는데 이를 이용해 어떤 에러가 발생했는지 출력할 수 있다.