[JavaScript] async와 await란?
async와 await는 자바스크립트의 비동기 처리 패턴 중 최근에 나온 문법이다. 자바스크립트는 싱글스레드 기반 언어이기 때문에 비동기 처리가 필수적이다. 비동기 처리는 결과를 예측할 수 없기 때문에 동기식의 처리가 필요하다. 대표적으로 앞에 글에서 작성했던 것처럼 promise, callback이 있다. async와 await는 기존 동기식 처리의 단점을 보완하고 가독성을 높혀주는 코드를 작성할 수 있다.
먼저 다시 한번 자바스크립트의 비동기처리에 대해서 얘기하고 가려 한다.
let first = 10;
let second = 20;
let result = 0;
function add(x, y) {
return x + y;
}
setTimeout(() => {
result = add(first, second);
console.log(result)
}, 1000);
first = 20;
40
위의 결과는 30이 나올 것 같지만, 40이 나오게 된다. 이유가 무엇일까?
자바스크립트는 작업을 큐에 넣고 순서대로 작업을 하게 된다. 이 때 작업이 큐에 들어가게 되는 과정에 대한 이해가 필요하다. 최초의 작업은 스크립트 파일이다. 그리고 그 다음에는 setTimeout()이 작업으로 큐에 들어가게 된다. 그래서 첫 번째 스크립트 파일이 완료된 후에 setTimeout() 함수가 실행이 된다. 따라서 스크립트 파일의 처음에는 first = 10 이었지만 마지막에는 first = 20이 되기 때문에 결과값으로는 40이 찍히게 된다. 이러한 상황을 처리하기 위해서 하는 작업이 동기식 처리인 promise, callback이 있었다고 정리했었다. 이번에는 promise와 async, await에 대해서 정리해보려 한다.
async & await
async는 promise의 코드를 깔끔하게 줄여주기 때문에 가독성을 높혀주는 효과가 있다. 사용법은 function 앞에 async만 붙여주면 되고 비동기로 처리되는 부분 앞에 await만 붙여주면 된다. 그리고 한가지 알아둬야 할 점은 await 뒤에 오는 부분은 반드시 promise를 반환해주어야 하고, async가 붙은 function도 promise를 반환해야 한다는 점이다. 사용법의 예시는 아래와 같다.
async function test() {
// logic
}
변수 = async() => {
// logic
}
그러면 이번에는 promise와 async & await를 사용했을 때 어떤 차이가 있는지를 알아보자.
let asyncFunc1 = (msg) => {
new Promise((resolve) => {
setTimeout(() => {
resolve(`func1 : ${msg}`);
}, 1000);
})
};
let asyncFunc2 = (msg) => {
new Promise((resolve) => {
setTimeout((resolve) => {
resolve(`func2 : ${msg}`);
}, 1000)
})
}
위와 같이 promise를 반환하면 함수 2개가 있다고 가정하자. 아래는 promise를 썼을 때의 예시이다.
function promiseMain() {
asyncFunc1('Hello').then((result) => {
console.log(result);
return asyncFunc2('world')
}).then((result) => {
console.log(result);
})
}
이번에는 async & await를 사용하였을 때의 코드이다.
async function asyncMain() {
let result = await asyncFunc1('Heello');
console.log(result);
result = await asyncFunc2('world');
console.log(result);
}
이렇게 짧은 코드로만 비교하여도 확실히 async & await을 사용하는 것이 promise보다 가독성이 좋다는 것을 알 수 있다.
async & await 예제
function asyncItem() {
return new Promise((resolve, reject) => {
var item = [1, 2, 3];
resolve(item);
});
}
async function logItems() {
var resultItem = await asyncItem();
console.log(resultItem);
}
asyncItem 함수는 Promise()를 객체를 반환하는 함수이다. resolve() 함수를 사용했기 때문에 item 배열을 반환해야 한다. 만약 await를 사용하지 않고 promise(), then()을 사용해야 하는데 이거를 비동기적 사고를 하면서 코드를 작성해야 하고 코드가 좀 길어진다면 가독성도 떨어지고 머리도 아플 것이다.
async & await 예외 처리
async & await에서 예외를 처리하는 방법은 try ~ catch이다. 프로미스에서 예외 처리를 위해 .catch()를 이용했던 것처럼 async에서는 catch { } 를 이용하면 된다.
async function test() {
try {
var user = await fetchUser();
if (user.id === 1) {
var todo = await fetchTodo();
console.log(todo.title);
}
} catch(err) {
console.log(error);
}
}
Reference
https://joshua1988.github.io/web-development/javascript/js-async-await/