Node.js는 Chrome의 V8 JavaScript 엔진을 기반으로 구축된 이벤트 중심의 non-blocking I/O 플랫폼입니다. 웹 서버를 포함하여 확장 가능한 네트워크 애플리케이션을 구축하는 데 널리 사용됩니다. 이러한 애플리케이션을 구축할 때 콜백 지옥(callback hell) 문제가 발생할 수 있습니다. 이는 여러 개의 중첩된 콜백이 있어 코드를 읽고 유지 관리하기 어렵게 만드는 문제를 의미합니다.
이 글에서는 Express 웹 프레임워크와 TypeScript를 사용하여 Node.js 애플리케이션을 구축할 때 콜백 지옥을 피하는 방법에 대해 설명합니다.
Promises
Promises 은 보다 읽기 쉽고 관리하기 쉬운 방식으로 비동기 작업을 처리하는 방법입니다. 이는 아직 사용할 수 없지만 미래에는 사용할 수 있는 값을 나타냅니다. Promise를 서로 연결하면 여러 비동기 작업을 순차적으로 처리할 수 있습니다.
Node.js에서 Promise를 사용하는 예는 다음과 같습니다.
function getData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Data received!');
}, 1000);
});
}
getData()
.then((data) => {
console.log(data);
})
.catch((error) => {
console.error(error);
});
이 예에서 getData
는 1초 후에 해결되는 약속을 반환합니다. 그런 다음 .then
메서드를 사용하여 확인된 값을 처리하고 .catch
메서드를 사용하여 오류를 처리할 수 있습니다.
Async/Await
Async/await 는 Promise 위에 추가되는 Syntatic Sugar(문법 설탕) 으로, 비동기 작업 작업을 더 쉽게 만듭니다. 이를 통해 동기적으로 보이는 비동기 코드를 작성할 수 있으므로 읽고 유지하기가 더 쉬워집니다.
컴퓨터 과학에서 Syntactic sugar(구문 설탕)은 더 쉽게 읽거나 표현하도록 설계된 프로그래밍 언어 내의 구문입니다. 그것은 인간이 사용하기에 언어를 "더 달콤"하게 만듭니다. 사물을 더 명확하고 간결하게 표현하거나 일부 사람들이 선호하는 대체 스타일로 표현할 수 있습니다. 위키백과
Node.js에서 async/await를 사용하는 예는 다음과 같습니다.
function getData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Data received!');
}, 1000);
});
}
async function main() {
try {
const data = await getData();
console.log(data);
} catch (error) {
console.error(error);
}
}
main();
이 예에서 main
은 wait
키워드를 사용하여 getData
함수의 확인된 값을 기다리는 비동기 함수입니다. try/catch
블록을 사용하여 오류를 처리할 수 있습니다.
Promisify
Promisify는 callback-based 함수를 promise-based 함수로 변환할 수 있도록 Node.js에서 제공하는 유틸리티 함수입니다. 이는 Promise를 사용하지 않는 오래된 라이브러리나 모듈로 작업할 때 유용할 수 있습니다.
Node.js에서 promisify를 사용하는 예는 다음과 같습니다.
const fs = require('fs');
const { promisify } = require('util');
const readFile = promisify(fs.readFile);
async function main() {
try {
const data = await readFile('file.txt', 'utf8');
console.log(data);
} catch (error) {
console.error(error);
}
}
main();
예에서는 util.promisify
를 사용하여 Node.js의 fs.readFile
함수를 promise-based 함수로 변환합니다. 그런 다음 Promise 기반 함수를 사용하여 file.txt
파일의 내용을 읽습니다.
Use Control Flow Libraries
복잡한 비동기 코드로 작업하는 경우 Promise와 async/await 만으로는 코드를 깔끔하고 유지 관리하기 쉽도록 유지하는 데 충분하지 않다는 것을 알 수 있습니다. 이 경우 제어 흐름(flow library) 라이브러리를 사용하여 비동기 코드를 관리하는 데 도움을 받을 수 있습니다.
제어 흐름 라이브러리는 비동기 작업의 흐름을 관리하는 방법을 제공하여 해당 작업이 올바른 순서로 실행되고 오류가 적절하게 처리되도록 합니다. Node.js의 인기 있는 제어 흐름 라이브러리로는 Async, Bluebird 및 Q가 있습니다.
다음은 Async 라이브러리를 사용하여 일련의 비동기 작업을 관리하는 방법에 대한 예입니다.
const async = require('async');
const fs = require('fs');
async.series(
[
(callback) => {
fs.readFile('file1.txt', 'utf8', callback);
},
(callback) => {
fs.readFile('file2.txt', 'utf8', callback);
},
(callback) => {
fs.readFile('file3.txt', 'utf8', callback);
},
],
(error, results) => {
if (error) {
console.error(error);
} else {
console.log(results);
}
}
);
이 예에서는 async.series
메서드를 사용하여 일련의 비동기 작업(이 경우 세 파일의 내용 읽기)을 순서대로 실행합니다. 모든 작업이 완료되면 최종 콜백이 호출되고 결과 배열을 받습니다.
결론
콜백 지옥은 Node.js에서 비동기 코드 작업을 어렵고 실망스럽게 만들 수 있지만, 이를 방지하기 위해 사용할 수 있는 많은 전략은 위과 같습니다.
'Backend > NodeJS' 카테고리의 다른 글
[Node.js] Winston 사용하여 로깅하기 (1) | 2024.09.27 |
---|---|
Node.js, Express를 사용하여 간단한 웹 크롤러 만들기 (0) | 2023.11.30 |
NVM 설치 및 사용 방법 (0) | 2022.11.13 |
node-gyp 설치 오류 해결 방법 (0) | 2022.10.22 |
npm install 시 gyp ERR! 해결 방법 (1) | 2022.10.18 |
IT 기술과 개발 내용을 포스팅하는 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!