Node.js 8 LTS 릴리스와 async/await 도입

Node.js 8 릴리스

오늘 Node.js 8이 정식 릴리스되었다. 가장 큰 변화는 V8 5.8 엔진 업데이트로 인한 네이티브 async/await 지원이다. 기존에는 Babel을 통해서만 사용할 수 있었는데, 이제 트랜스파일 없이 바로 사용 가능하다.

기존 콜백 패턴의 문제

프로젝트에서 데이터베이스 조회 후 외부 API를 호출하는 로직이 있었다. Promise 체이닝으로 작성했지만 중첩이 깊어지면서 가독성이 떨어졌다.

function getUserData(userId) {
  return db.findUser(userId)
    .then(user => {
      return api.fetchProfile(user.profileId)
        .then(profile => {
          return api.fetchPosts(profile.id)
            .then(posts => {
              return { user, profile, posts };
            });
        });
    });
}

async/await으로 개선

같은 로직을 async/await으로 재작성했다. 훨씬 읽기 쉬워졌다.

async function getUserData(userId) {
  const user = await db.findUser(userId);
  const profile = await api.fetchProfile(user.profileId);
  const posts = await api.fetchPosts(profile.id);
  return { user, profile, posts };
}

에러 처리도 try-catch로 일관되게 할 수 있다.

async function getUserData(userId) {
  try {
    const user = await db.findUser(userId);
    const profile = await api.fetchProfile(user.profileId);
    const posts = await api.fetchPosts(profile.id);
    return { user, profile, posts };
  } catch (error) {
    logger.error('Failed to fetch user data:', error);
    throw error;
  }
}

Express 미들웨어 적용

Express 라우터에서도 바로 적용했다. async 함수에서 발생한 에러는 별도 에러 핸들러가 필요하다.

app.get('/users/:id', async (req, res, next) => {
  try {
    const data = await getUserData(req.params.id);
    res.json(data);
  } catch (error) {
    next(error);
  }
});

마이그레이션 계획

당장 모든 코드를 전환하기보다는 새로 작성하는 코드부터 async/await을 적용하기로 했다. 10월에 LTS로 전환되면 프로덕션 서버도 업그레이드할 예정이다.