Node.js - 콜백 개념
안녕하세요, 열정적인 프로그래머 되고자 하는 분들! 오늘 우리는 Node.js 콜백의 세계로 흥미로운 여정을 시작할 것입니다. 여러분의 친절한 이웃 컴퓨터 선생님이자 저는 이 개념을 단계별로 안내해드리겠습니다. 프로그래밍에 새로운 분이라면 걱정하지 마세요 - 우리는 기본부터 시작하여 점진적으로 올라갈 것입니다. 그러니 커피(또는 차, 당신의 취향에 따라)를 한 잔 마시고, 이제 시작해보겠습니다!
콜백이란?
이미 바쁜 식당에서 상상해보세요. 웨이터에게 주문을 넣은 후, 음식을 기다리며 앉아 친구들과 이야기 나눕니다. 웨이터는 음식이 준비되면 "콜백"을 해줍니다. 프로그래밍에서 콜백은 이와 같은 개념입니다!
Node.js에서 콜백은 다른 함수에 인수로 전달되고, 해당 함수가 작업을 완료한 후 실행되는 함수입니다. 이는 특정 코드가 이전 작업이 완료되기 전에 실행되지 않도록 보장하는 방법입니다.
간단한 예제를 보겠습니다:
function greet(name, callback) {
console.log('Hello, ' + name + '!');
callback();
}
function sayGoodbye() {
console.log('Goodbye!');
}
greet('Alice', sayGoodbye);
이 예제에서 sayGoodbye
는 우리의 콜백 함수입니다. 이를 greet
함수에 전달하고, greet
함수는 인사를 출력한 후 이를 호출합니다. 이 코드를 실행하면 다음과 같은 결과를 보게 됩니다:
Hello, Alice!
Goodbye!
콜백을 통해 우리는 작업의 순서를 제어할 수 있어, 인사 뒤에 "Goodbye!"가 출력되도록 할 수 있습니다.
블록킹 코드 예제
콜백을 더 깊이 이해하기 전에, 콜백을 사용하지 않을 때 어떤 일이 일어나는지 보겠습니다. 이를 "블록킹 코드"라고 부르며, 이는 후속 코드의 실행을 중단하거나 (또는 블록) 현재 작업이 완료될 때까지 기다립니다.
블록킹 코드의 예제를 보겠습니다:
const fs = require('fs');
// 블록킹 코드
const data = fs.readFileSync('example.txt', 'utf8');
console.log(data);
console.log('File reading finished');
console.log('Program ended');
이 예제에서 readFileSync
은 동기적 함수로 파일을 읽습니다. 프로그램은 파일이 완전히 읽혀질 때까지 다음 줄로 이동하지 않습니다. 파일이 크다면, 이는 프로그램에서 눈에 띄는 지연을引き起こ 수 있습니다.
비블록킹 코드 예제
이제 콜백을 사용하여 코드를 비블록킹으로 만드는 방법을 보겠습니다:
const fs = require('fs');
// 비블록킹 코드
fs.readFile('example.txt', 'utf8', (err, data) => {
if (err) {
console.error('Error reading file:', err);
return;
}
console.log(data);
});
console.log('File reading started');
console.log('Program ended');
이 비블록킹 버전에서 readFile
은 마지막 인수로 콜백 함수를 받습니다. 파일 읽기가 완료되거나 오류가 발생할 때 이 함수가 호출됩니다. 프로그램은 파일을 읽는 것을 기다리지 않고, 즉시 다음 줄을 실행합니다.
출력은 다음과 같을 수 있습니다:
File reading started
Program ended
[Contents of example.txt]
"File reading started"와 "Program ended"가 파일 내용 전에 출력되는 것을 알 수 있습니다. 이는 파일 읽기가 비동기적으로 일어나, 나머지 프로그램이 계속 실행되기 때문입니다.
화살표 함수로 콜백
모던 자바스크립트에서는 화살표 함수를 콜백으로 자주 사용합니다. 이는 더 간결한 문법을 제공합니다. 이전 인사 예제를 화살표 함수로 다시 작성해보겠습니다:
function greet(name, callback) {
console.log('Hello, ' + name + '!');
callback();
}
greet('Bob', () => {
console.log('Goodbye!');
});
여기서 우리는 별도의 sayGoodbye
함수를 정의하지 않고, greet
함수 호출 시 직접 화살표 함수를 사용합니다. 이는 콜백이 짧고 다른 코드에서 재사용할 필요가 없을 때 특히 유용합니다.
콜백 헬과 이를 피하는 방법
프로그램이 더 복잡해지면서, 콜백을 콜백 안에嵌套할 수 있습니다. 이는 "콜백 헬" 또는 "피라미드의 독"으로 알려진 상황을 초래할 수 있습니다. 다음과 같이 보입니다:
asyncOperation1((error1, result1) => {
if (error1) {
handleError(error1);
} else {
asyncOperation2(result1, (error2, result2) => {
if (error2) {
handleError(error2);
} else {
asyncOperation3(result2, (error3, result3) => {
if (error3) {
handleError(error3);
} else {
// 그리고 이어서...
}
});
}
});
}
});
이를 피하기 위해 다음과 같은 기술을 사용할 수 있습니다:
- 명명된 함수 대신 익명 함수 사용
- 프롬이스
- 어싱크/어와이트 (프롬이스를 밑바탕으로 사용)
다음 표는 이 방법들을 요약합니다:
방법 | 설명 | 장점 | 단점 |
---|---|---|---|
명명된 함수 | 각 콜백에 별도의 함수 정의 | 가독성 향상 | 여전히 많은嵌套 함수 가능 |
프롬이스 |
.then() 체인 사용 |
嵌套 감소, 더 나은 오류 처리 | 프롬이스 개념 이해 필요 |
어싱크/어와이트 |
async 함수와 await 키워드 사용 |
동기적 코드처럼 보임, 매우 가독적 | 프롬이스와 어싱크/어와이트 개념 이해 필요 |
결론
콜백은 Node.js와 일반적으로 자바스크립트에서 중요한 개념입니다. 이는 비동기 작업을 효과적으로 처리하여 프로그램을 더 효율적이고 응답성 있게 만듭니다. 프로그래밍 여정을 계속하면서 자주 마주칠 콜백을 잘 이해하면 더 능숙한 개발자가 될 수 있습니다.
콜백을 마스터하려면 연습이 필요합니다. 즉시 이해가 되지 않는다면 낙寞해하지 마세요 - 계속 코딩하고 실험하다 보면 곧 콜백을 마스터할 수 있을 것입니다!
미래의 개발자 여러분, 행복하게 코딩하세요! 그리고 프로그래밍의 세계에서 우리는 작별 인사를 하지 않습니다 - 우리는 단지 나중에 다시 콜백할 뿐입니다!
Credits: Image by storyset