JavaScript의 런타임 모델은 코드의 실행, 이벤트의 수집과 처리, 큐에 대기 중인 하위 작업을 처리하는 이벤트 루프에 기반하고 있으며, C 또는 Java 등 다른 언어가 가진 모델과는 상당히 다릅니다. -mdn
최근 면접을 보면서 JS의 이벤트 루프에 대한 질문을 받았는데, 대답하지 못했다.
이 게시글을 통해 JavaScript의 이벤트 루프(Event Loop)에 대해 정리해보려고 한다.
이벤트 루프에 대해 알기 전에 JavaScript의 특징에 대해 먼저 알아보자.
JavaScript는 단일 스레드 언어(single-threaded language)로 한 번에 하나의 작업만 처리할 수 있다.
하지만 실제로 동작하는 웹 애플리케이션은 많은 task가 동시에 처리되는 것처럼 느껴진다.
이처럼 JavaScript가 동시에 여러가지 일을 하는 것처럼 느낄수 있는 건, JavaScript가 비동기로 작동하기 때문이다.
하지만, JavaScript 언어 자체가 비동기 동작을 지원하는 것은 아니다.
비동기로 동작하는 핵심 요소는 JavaScript가 아닌 브라우저가 가지고 있다.
그 브라우저의 구조에 대해서 알아보자.
Memory Heap : 메모리 할당이 일어나는 곳이다.
Call Stack : 실행된 코드의 환경을 저장하는 자료 구조로, 함수 호출 시 이곳에 저장된다. 함수를 호출하면 해당 함수의 기록을 스택 맨 위에 추가하고, 우리가 함수 결과 값을 반환하면 스택에 쌓여있던 함수는 제거된다. (선입후출)
Web APIs : 브라우저에서 제공하는 API로 DOM, Ajax, TimeOut 등이 있다.
CallStack에서 실행된 비동기 함수는 Web API를 호출하고, Web API는 콜백 함수를 Task Queue에 넣는다.
Callback Queue : 비동기적으로 실행된 콜백 함수를 저장하는 자료 구조로, Call Stack과 다르게 가장 먼저 들어온 함수를 가장 먼저 처리한다. (선입선출)
Event Loop : Event Loop는 Call Stack과 Callback Queue의 상태를 체크하여,
Call Stack이 빈 상태가 되면, Callback Queue의 첫번째 콜백을 꺼내 Call Stack에 추가한다.
이러한 반복적인 행동을 틱(tick) 이라 부른다.
console.log(1);
setTimeout(
function cb() {
console.log(2);
}
,0);
console.log(3);
이 코드를 실행하면 콘솔창엔 어떤 순서로 출력이 될까?
바로 1, 3, 2 순으로 실행이 된다.
각 구성요소들이 어떻게 동작하는지를 이해하며 그 이유를 알아보자.
console.log(1)
가 Call Stack에 추가된다. 그 이후 실행되어 콘솔에 출력된 뒤, Call Stack에서 제거된다.
그 다음, setTimeOut(...)
이 Call Stack에 추가된다.
setTimeOut(...)
가 실행이 되며 브라우저가 제공하는 timer Web API를 호출하고 Call Stack에서 제거된다.
console.log(3)
이 Call Stack에 추가된다. 그 이후 실행되어 콘솔에 출력된 뒤, Call Stack에서 제거된다.
setTimeOut(...)
함수의 0ms만큼의 시간이 지난 뒤 Callback으로 전달한 cb
함수가 Callback Queue에 추가된다.
Event Loop는 Call Stack이 비어있는 것을 확인하고 Callback Queue를 살펴보고, 함수 cb
를 발견한 후 Call Stack에 cb
함수를 추가한다.
cb
함수가 실행 되고 내부의 console.log(2)
가 Call Stack에 추가된다.
console.log(2)
가 콘솔에 출력되고 Call Stack에서 제거되고, cb
함수도 제거된다.
3번의 예제를 통해 우린 실제로 이벤트 루프(Event Loop)는 Call Stack과 Callback Queue의 상태를 체크하여 Call Stack이 빈 상태가 되면, Callback Queue의 첫번째 콜백을 꺼내 Call Stack에 추가한다는 사실을 알 수 있다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Event_loop
https://medium.com/sjk5766/javascript-%EB%B9%84%EB%8F%99%EA%B8%B0-%ED%95%B5%EC%8B%AC-event-loop-%EC%A0%95%EB%A6%AC-422eb29231a8
🔥