본문으로 바로가기

async/await

category Node JS/ES2015+ 2022. 4. 24. 23:02

노드 7.6부터 지원되는 기능 이며 ES2017에서 추가되어 알아두면 정말 편리한 기능 이다. 특히 노드처럼 비동기 위주로 프로그래밍 할때 도움이 된다.

 

프로미스가 콜백 지옥을 해결했다지만 여전히 코드가 장황하고 then 과 catch가 계속 반복되기 때문이다. async/await 문법은 프로미스 를 사용한 코드를 한번 더 깔끔하게 줄인다.

 

function findAndSaveUser(Users) {
  Users.findOne({})
    .then((user) => {
      user.name = 'zero';
      return user.save();
    })
    .then((user) => {
      return Users.findOne({ gender: 'm' });
    })
    .then((user) => {
      // 생략
    })
    .catch(err => {
      console.error(err);
    });
}

콜백과 다르게 코드의 깊이가 깊어지진 않지만, 코드는 여전히 길다.

async/await 문법을 사용하면 다음과 같이 바꿀수 있다.

 

async function이라는 것이 추가된다.

async function findAndSaveUser(Users) {
  let user = await Users.findOne({});
  user.name = 'zero';
  user = await user.save();
  user = await Users.findOne({ gender: 'm' });
  // 생략
}

놀라울정도로 코드가 짧아졌다.

함수 선언부를 일반 함수 대신 async function으로 교체한 후 프로미스 앞에 await을 붙인다.

이제 함수는 해당 프로미스가 resolve될 때까지 기다린 다음 로직으로 넘어간다 예를 들면 await User.findOne({})이 resolve될때까지 기다린다음에 user 변수를 초기화 하는것이다.

 

위코드는 에러를 처리하는 부분(프로미스가 reject된 경우)이 없으므로 다음과 같은 추가 작업이 필요하다

async function findAndSaveUser(Users) {
  try {
    let user = await Users.findOne({});
    user.name = 'zero';
    user = await user.save();
    user = await Users.findOne({ gender: 'm' });
    // 생략
  } catch (error) {
    console.error(error);
  }
}

try/catch문으로 로직을 감쌌다. 프로미스의 catch 메서드 처럼 try/catch 문의 catch가 에러를 처리한다.

화살표함수도 async와 같이 사용할수있다.

const findAndSaveUser = async (Users) => {
  try {
    let user = await Users.findOne({});
    user.name = 'zero';
    user = await user.save();
    user = await Users.findOne({ gender: 'm' });
    // 생략
  } catch (error) {
    console.error(error);
  }
};

for문과 async/await을 같이써서 프로미스를 순차적으로 실행할수있다. for문과 함께 쓰는것은 노드 10버전부터 지원하는 ES2018 문법이다.

const promise1 = Promise.resolve('성공1');
const promise2 = Promise.resolve('성공2');
(async () => {
  for await (promise of [promise1, promise2]) {
    console.log(promise);
  }
})();

for await if 문을 사용해서 프로미스 배열을 순회하는 모습이다. async 함수의 반환값은 항상 promise로 감싸진다 따라서 실행 후 then을 붙이거나 또 다른 async 함수 안에서 await을 붙여서 처리할수있다.

async function findAndSaveUser(Users) {
  // 생략
}

findAndSaveUser().then(() => { /* 생략 */ });
// 또는
async function other() {
  const result = await findAndSaveUser();
}

앞으로 중첩되는 콜백 함수가 있다면 프로미스를 거쳐 async/await 문법으로 바꾸는 연습을 해봐야겠다.

'Node JS > ES2015+' 카테고리의 다른 글

프로미스  (0) 2022.04.24
클래스  (0) 2022.04.24
ES2015+ 란??  (0) 2022.04.24
구조분해 할당  (0) 2021.11.27
화살표 함수  (0) 2021.11.27