Node.js 8에서 util.promisify로 콜백 함수 Promise화하기

배경

프로젝트에서 Node.js 6에서 8로 마이그레이션을 진행했다. 기존 코드베이스에 콜백 헬이 많아서 고민하던 중 util.promisify를 발견했다.

기존 코드

파일 읽기 작업을 연속으로 수행할 때 콜백이 중첩되는 문제가 있었다.

const fs = require('fs');

fs.readFile('config.json', 'utf8', (err, data) => {
  if (err) return console.error(err);
  const config = JSON.parse(data);
  
  fs.readFile(config.dataPath, 'utf8', (err, data) => {
    if (err) return console.error(err);
    // 처리 로직
  });
});

util.promisify 적용

const fs = require('fs');
const util = require('util');

const readFile = util.promisify(fs.readFile);

async function loadData() {
  try {
    const configData = await readFile('config.json', 'utf8');
    const config = JSON.parse(configData);
    const data = await readFile(config.dataPath, 'utf8');
    return data;
  } catch (err) {
    console.error(err);
  }
}

결과

  • async/await 문법과 함께 사용하니 동기 코드처럼 읽힌다
  • 에러 핸들링이 try/catch로 통일되어 명확해졌다
  • 기존 fs 모듈을 그대로 활용할 수 있어서 좋았다

다만 콜백이 (err, value) 형태가 아니면 동작하지 않으니 주의가 필요하다. 커스텀 콜백은 직접 Promise로 감싸는 게 나았다.