비동기 함수(Asynchronous Function)란?
비동기 함수는 작업의 완료를 기다리지 않고 프로그램이 계속 실행되도록 만드는 함수입니다. 즉, 대기하지 않습니다! 이러한 방식 덕분에 사용자가 체감하는 대기 시간이 크게 줄어듭니다. 사실 자바스크립트라는 언어 자체가 근본적으로 비동기적으로 동작하도록 설계되어 있습니다.
예를 들어, 실행에 많은 시간이 소요되는 무거운 요청(대용량 데이터 조회, 외부 API 호출 등)을 처리한다고 가정해 보겠습니다. 이를 동기(synchronous) 방식으로 처리하면 요청이 완료될 때까지 프로그램 전체가 멈추게 되고, 그동안 사용자는 다른 어떤 작업도 수행할 수 없습니다.
따라서 일반적으로 무겁고 시간이 오래 걸리는 작업을 수행할 때는 비동기 코드를 사용하는 것이 좋습니다.
자바스크립트 비동기 함수 예제
console.log('One');
jQuery.get('page.html', function (data) {
console.log('Two');
});
console.log('Three');실행 결과
One, Three, Two
여기서 주목할 점은 출력 순서입니다. jQuery.get()은 서버에서 page.html을 가져오는 비동기 요청이므로, 콜백 함수 안의 'Two'는 서버 응답이 도착한 이후에야 실행됩니다. 결과적으로 출력 순서는 One → Three → Two가 되며, 이것이 바로 비동기 함수가 '기다리지 않는다'는 의미입니다.
Node.js의 이벤트 루프(Event Loop)란?
그렇다면 Node.js에서 이벤트 루프란 무엇일까요? 이벤트 루프는 스레드 스케줄(thread schedule) 내부에 생성되며, 특정 시점에 스레드가 어떤 작업을 수행해야 하는지를 결정하는 역할을 담당합니다.
모든 Node.js 애플리케이션은 들어오는 연결(incoming connection), I/O 완료, 타임아웃 만료, 프로미스(Promise) 처리 등 다양한 이벤트에 반응하여 실행되는 콜백(callback)들로 구성되어 있습니다. 그리고 메인 스레드, 즉 우리가 흔히 '이벤트 루프'라고 부르는 것이 이 모든 콜백을 실행합니다.
이벤트 루프가 실행되는 동안 매 반복(iteration)마다 Node는 현재 대기 중인 비동기 I/O 작업이나 타이머가 있는지 확인합니다. 만약 더 이상 아무것도 발견되지 않으면, Node는 해당 프로세스를 종료합니다.
이벤트 루프가 중요한 이유
Node.js는 단일 스레드(single-threaded) 기반으로 동작하지만, 논블로킹(non-blocking) I/O와 이벤트 루프 덕분에 적은 리소스로도 수많은 동시 연결을 효율적으로 처리할 수 있습니다. 이것이 Node.js가 I/O 중심 애플리케이션에서 강점을 보이는 핵심 이유입니다.