(수정) Promise 생성자 내 async, await 넣기 > 지양하는 방식

hanbinleejoy·2020년 12월 2일
0

javascript

목록 보기
1/1
post-thumbnail

async, await 또 다른 접근

사실 또 다른 접근이라기보다 제가 미처 알지 못했던 내용을 필기할겸 남기는 글입니다. 최근에 온라인 강의를 수강하다 '이렇게도 사용할 수 있구나'하는 부분에 대해 잊어버리기 전에 기록하려 합니다.

🔖 들어가기에 앞서

  • js에서 비동기처리?
  • Promise
  • async, await

이 부분에 대해 선수 지식이 있어야 합니다. (근데 저도 잘 모른다는게 함정...) 이 부분에 대해서도 차차 정리해보겠습니다. 그리고 Vue.js 관련 온라인 강의 내용 가지고 예시를 구성했습니다.

  • Vue.js
  • Vuex 사용법

이 부분에 대해서도 알면 제 필기내용이 더 잘 이해가 될 것입니다.

🔖 기존에 알고있던 Promise 사용방식

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 생성자 내부에 대해서는 딱히 생각해본 적이 없었습니다. (실행되기만 하면 된다고 생각했나보다.)

🔖 Promise 생성자 안에도 async, await 처리?

만약 서비스 로직 상 먼저 실행돼야 하는 부분에 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 처리를 해야 한다는 것입니다.

중요한 것은 awaitasync 환경 내에서 수행되어야 하기에

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 적용하는 위치만 주의하면 됩니다.

🔖 수정사항

  • 20.12.03

ESLint의 "no-async-promise-executor" 이슈

위에 내용을 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)
}

결론

  • dev server 돌릴 땐 문제가 없어서 no-async-promise-executor 이슈는 큰 문제가 아니지만
  • 실제 개발과 배포과정에서는 해당 eslint 규칙에 맞게 async를 Promise 생성자 안에 작성하는 방식은 지양해야 합니다.
    (강사님 답변 내용)
profile
#back_end💻 #developer👨‍💻 #I_LIKE_Build👍

0개의 댓글