사실 또 다른 접근이라기보다 제가 미처 알지 못했던 내용을 필기할겸 남기는 글입니다. 최근에 온라인 강의를 수강하다 '이렇게도 사용할 수 있구나'하는 부분에 대해 잊어버리기 전에 기록하려 합니다.
이 부분에 대해 선수 지식이 있어야 합니다. (근데 저도 잘 모른다는게 함정...) 이 부분에 대해서도 차차 정리해보겠습니다. 그리고 Vue.js 관련 온라인 강의 내용 가지고 예시를 구성했습니다.
이 부분에 대해서도 알면 제 필기내용이 더 잘 이해가 될 것입니다.
function p() {
return new Promise(resolve => {
setTimeout(() => {
console.log('내가 먼저 실행돼야해')
resolve('p func 실행 성공');
}, 1000);
});
}
async function asyncFunc() {
const msg = await p();
console.log(msg, ' 그 다음에 내가 실행돼야해');
}
asyncFunc();
내가 먼저 실행돼야해
p func 실행 성공, 그 다음에 내가 실행돼야해
이런 식으로 await는 Promise 객체를 반환하는 메서드를 대상으로 하기에 Promise 생성자 내부에 대해서는 딱히 생각해본 적이 없었습니다. (실행되기만 하면 된다고 생각했나보다.)
만약 서비스 로직 상 먼저 실행돼야 하는 부분에 await를 해야하는 부분이 존재하면 어떻게 해야되나. 예시로
fetchMovies ({ state, commit }, pageNum) {
return new Promise(async (resolve) => {
const res = await axios.get('영화사이트API')
commit('pushIntoMovies', res.data.Search)
resolve(res.data)
})
},
async searchMovies ({ commit, dispatch }) {
// state.loading = true
commit('updateState', {
loading: true,
movies: []
})
const { totalResults } = await dispatch('fetchMovies', 1)
// 이후 로직...
}
vuex
관련 store 처리 부분에서 actions 내에 위와 같이 처리했다고 가정해봅시다. fetchMovies
는 해당 영화사이트 API를 통해 원하는 영화 리스트 데이터를 가져오는 작업을 수행하는 Promise 반환 메서드입니다..
이 안에 axios.get
을 통해 영화데이터를 받아오는 부분을 수행해야 하는데 이 또한 비동기로 처리되면 안되기에 await
처리를 해주어야 합니다. Promise 생성자 안에 await
처리를 해야 한다는 것입니다.
중요한 것은 await
는 async
환경 내에서 수행되어야 하기에
return new Promise(async (resolve) => {
const res = await axios.get('영화사이트API')
//...
})
이렇게 생성자 내부 익명함수에 async
를 부여해야 합니다.
// 이렇게 하면 안됩니다.
async fetchMovies ({ state, commit }, pageNum) {
return new Promise(resolve => {
const res = await axios.get('영화사이트API')
//...
})
},
위와 같이 fetchMovies에 async
를 부여하면 안됩니다.
async
, await
는 필요할 때면 Promise 생성자 내부 함수인자에도 언제든 적용할 수 있는데 async
적용하는 위치만 주의하면 됩니다.
위에 내용을 lint를 실행했었는데 다음과 같은 에러가 발생했습니다.
Promise executor functions should not be async (no-async-promise-executor)
at src\store\movie.js:25:32:
관련 내용을 구글링해보니 eslint에서 이에 대한 내용을 언급해주셨더라구요.
(ESLint 언급 내용)
이에 대해서 강사님께서 직접 수정코드를 제시해주셨는데 다음과 같습니다.
function fetchMovies ({ state, commit }, pageNum) {
const promise = new Promise(resolve => {
const res = axios.get('영화사이트API')
resolve(res)
})
return promise.then(res => res.data)
}
no-async-promise-executor
이슈는 큰 문제가 아니지만