Node.js 8의 util.promisify로 콜백 지옥 탈출하기
문제 상황
레거시 API 서버를 유지보수하면서 콜백 중첩이 심각한 코드를 마주쳤다. fs, crypto 등 Node.js 기본 모듈을 사용하는 부분이 특히 심했다.
fs.readFile('config.json', 'utf8', (err, data) => {
if (err) return callback(err);
crypto.randomBytes(16, (err, buffer) => {
if (err) return callback(err);
// 계속 중첩...
});
});
util.promisify 도입
Node.js 8.0.0부터 util.promisify가 정식 지원된다. 콜백 스타일 함수를 Promise로 변환해주는 유틸이다.
const util = require('util');
const fs = require('fs');
const crypto = require('crypto');
const readFile = util.promisify(fs.readFile);
const randomBytes = util.promisify(crypto.randomBytes);
async function loadConfig() {
try {
const data = await readFile('config.json', 'utf8');
const buffer = await randomBytes(16);
return { config: JSON.parse(data), token: buffer.toString('hex') };
} catch (err) {
console.error('Error:', err);
throw err;
}
}
적용 결과
- 콜백 중첩 5단계 → async/await 플랫 구조로 변경
- 에러 핸들링이 try-catch로 통일되어 관리 용이
- 테스트 코드 작성 시 Promise 체이닝 활용 가능
주의사항
promisify는 Node.js 콜백 컨벤션(error-first callback)을 따르는 함수에만 사용 가능하다. 커스텀 콜백 형태는 직접 Promise wrapper를 작성해야 한다.
당분간은 기존 코드와 혼용하면서 점진적으로 마이그레이션할 예정이다.