async, await
async, await는 자바스크립트 비동기 처리 패턴의 최신 문법이다.
Promise와 Callback에서 주는 단점들을 해결하고 자바스크립트의 비동기적 사고 방식에서 벗어나 동기적(절차적)으로 코드를 작성할 수 있게 해준다.
기본 문법
async 함수의 기본 문법은 다음과 같다.
async function fetchData() {
await getUserList();
}
async 함수는 함수의 앞에 async를 붙여주고 함수의 내부 로직 중 비동기 처리 로직 앞에 await를 붙여주면 된다.
즉, Promise 객체를 반환하는 API 호출 함수 앞에 await를 붙이면 된다.
async function fetchData() {
var list = await getUserList();
console.log(list);
}
function getUserList() {
return new Promise(function(resolve, reject) {
var userList = ['user1', 'user2', 'user3'];
resolve(userList);
});
}
fetchData() 함수에서 getUserList() 함수를 호출하고 나면 Promise 객체가 반환된다.
그리고 그 Promise는 실행이 완료된 상태(resolve)이며 실행의 결과로 userList 배열을 반환하고, 따라서 fetchData()를 호출하면 userList의 배열이 출력된다.
loginUser() {
axios.get('https://jsonplaceholder.typicode.com/users/1')
.then(response => {
if (response.data.id === 1) {
axios.get('https://jsonplaceholder.typicode.com/todos')
.then(response => {
console.log(response.data);
})
.catch(err => {
console.log(err);
});
}
})
.catch(err => {
console.log(err);
});
}
axios를 통해 정보를 가져오고 인증을 통과하면 한번 더 데이터를 가져오는 로직이다.
2번의 api호출이 필요하여 then()안에 또 api를 호출하였다.
api의 호출이 많아 질수록 then안에 api호출, 패턴이 반복된다.
다음 코드를 보며 차이점을 알아보자.
async loginUser1() {
let response = await axios.get('https://jsonplaceholder.typicode.com/users/1');
if (response.data.id === 1) {
let list = await axios.get('https://jsonplaceholder.typicode.com/todos');
}
}
코드 라인수가 많이 줄었고 흐름이 한눈에 보인다.
아주 직관적인 코드로 변경이 되었다.
근데 promise객체를 바로 컨트롤 할때는 catch라는 function을 통해 에러 처리를 했는데 await는 catch같은 메소드가 따로 없다.
그래서 async await를 사용할때 에러 처리는 try catch를 이용한다.
async loginUser1() {
try() {
let response = await axios.get('https://jsonplaceholder.typicode.com/users/1');
if (response.data.id === 1) {
let list = await axios.get('https://jsonplaceholder.typicode.com/todos');
}
} catch (err) {
console.log(err);
}
}
Promise에서 여러개의 then() chaining을 하고 마지막에만 catch를 넣어줘도 모든 then의 예외를 처리하듯이 try내의 로직 중 에러가 발생한다면 catch에서 모두 에러를 잡아준다.
단, promise의 catch는 네트워크 처리중의 에러만 잡아주지만, try catch의 catch는 비동기 처리 뿐만 아니라 자바스크립트 코드의 에러 또한 잡아주기 때문에 좀 더 포괄적인 에러 처리가 가능하다.
promise기반의 코드를 async, await 기반으로 변경 해보자.
// actions.js
// 기존코드
FETCH_LIST1({ commit }, pageName) {
return fetchList(pageName)
.then(res => {
commit('SET_LIST', res.data);
return res;
})
.catch(err => {
console.log(err);
});
}
// 변경코드
async FETCH_LIST2({ commit }, pageName) {
try {
const response = await fetchList(pageName);
commit('SET_LIST', res.data);
return response;
} catch (err) {
console.log(err);
}
}