
자바스크립트의 특징 중 하나는, 그것이 'single thread' 기반의 언어라는 것입니다. 멀티 스레드와는 달리 동시에 하나의 작업만을 처리할 수 있는 언어인 것입니다.
하지만 여러 함수가 서로 복합적으로 얽혀 있고, 하나의 함수가 끝날때 까지 다른 함수들이 아무것도 하지 못하는 상황이 발생한다면 어떨까요. 시간이 엄청나게 지연되는 치명적인 문제가 발생할 것입니다.
다행스럽게도 자바스크립트는 비동기적으로 함수를 처리하여 그러한 문제를 해결합니다.
그렇게 동작하는 자바스크립트의 작동원리를 알아보겠습니다.
누군가는 이벤트 루프를 알지 못하면 자바스크립트를 알지 못하는 것이라고 하기도 합니다.
다음의 코드를 예로 들어보겠습니다.
console.log('Hi');
setTimeout(function cb1() {
console.log('cb1');
}, 5000);
console.log('Bye');
위의 코드는 아래의 그림과 같이 작동합니다.

구체적인 작동 순서는 다음과 같습니다.
- 브라우저 콘솔, 콜스택, 콜백큐 등 모든 것이 깨끗하게 비워져 있습니다.
- 가장 먼저 console.log('Hi')가 콜스택에 쌓입니다.
- console.log('Hi')가 실행이 되어
- 콜스택에서 빠져 나갑니다.
- 다음으로 cb1 함수가 실행되는데, cb1은 5초 뒤에 작동한다고 설정해봅시다. 하지만 그렇다고 cb1을 5초 동안이나 콜스택에 놔둘 수는 없습니다. 왜냐하면 그러는 동안 다른 함수들이 5초 동안이나 기다려야 하기 때문입니다.
- 이 때 브라우저가 웹 API의 일환인 타이머를 생성합니다. cb1은 Web APIs(노드의 경우 백그라운드)로 보내지며, 타이머가 카운트 다운을 처리합니다.
- setTimeout()이 완료되고 콜스택을 빠져 나갑니다.
- console.log('Bye')가 콜스택에 추가되고,
- 실행이 되어 브라우저 콘솔에 찍힙니다.
- 그리고 콜스택을 빠져나갑니다.
- 기존에 설정했던 5초가 지나면 타이머가 완료되고, cb1을 콜백큐에 밀어 넣습니다.
- 이벤트 루프는 콜스택이 비었는지 확인을 하고, 비었다면 cb1을 콜백큐에서 가져다가 콜스택에 밀어 넣습니다.
- cb1이 콜스택에 쌓이고 실행됩니다.
- cb1 안에 있던 console.log('cb1')가 콜스택에 쌓이고 실행됩니다.
- console.log('cb1')이 콜스택을 빠져 나갑니다.
- 마지막으로 cb1도 콜스택을 빠져 나갑니다.
이처럼 싱글 스레드 기반의 자바스크립트를 멀티 스레드인 것처럼 사용할 수 있습니다.
최대한 많은 함수를 백그라운드로 넘겨서 더 많은 함수를 동시에 작동시키면 훨씬 더 효율적일 것 같습니다.
하지만 노드에서는 백그라운드로 보낼 수 있는 함수들을 제한을 해두었습니다. 예를 들어, setTimeout(), setInterval(), fs 명령어, 네트워크 요청 등의 메서드만 백그라운드에서 작동할 수 있습니다.