❓이벤트 루프(Event Loop)란?
이벤트 루프에 대해 설명하기에 앞서 자바스크립트의 특징을 짚고 넘어가보자
싱글쓰레드란 여러 개의 작업이 있더라도 한 번에 하나의 작업만 수행할 수 있는 것이다.
하지만 JavaScript를 사용해 보면 멀티쓰레드처럼 동시에 여러 작업을 수행할 수 있다는 것을 알 수 있다.
그 이유는 JavaScript의 메인쓰레드인 이벤트 루프가 싱글 쓰레드이기 때문이다.
하지만 이벤트 루프만 독립적으로 실행되는것이 아닌 웹 브라우저나 NodeJS 같은 멀티쓰레드 환경에서 실행되고 이를 적절하게 사용함으로써 멀티쓰레드처럼 사용이 가능한 것이다.
JavaScript 엔진은 코드를 이해하고 실행을 도와주는 역할을 한다. 그중에서도 가장 대표적인 엔진으로는 Google의 V8 엔진이고 이외에도 각 브라우저 별로 여러 가지 엔진들이 존재하지만 JavaScript 엔진은 크게 Memory Heap
과 Call Stack
으로 이루어져 있다.
먼저 Memory Heap
에 있는 사용자가 작성한 코드들은 Call Stack에서 Stack 방식으로 쌓이며 코드를 실행하게 되는데 이때 동기 함수들은 그대로 실행하게 되고 비동기 함수들은 Web API로 처리하게 되며 일을 분배한다.
Call Stack에서 실행된 비동기 함수는 Web API
에서 처리를 하게 되고 그동안에 Call Stack은 나머지 동기 함수들을 처리하게 된다.
Web API
는 비동기 함수들을 처리하며 작업이 완료된 비동기 함수들을 Callback Queue
로 넘겨주게 된다.
JavaScript 런타임은 메시지 큐, 즉 처리할 메시지의 대기열을 사용한다. 각각의 메시지에는 메시지를 처리하기 위한 함수가 연결되어 있다.
이벤트 루프
의 임의 시점에, 런타임은 대기열에서 가장 오래된 메시지부터 큐에서 꺼내 처리하기 시작한다. 이를 위해 런타임은 꺼낸 메시지를 매개변수로, 메시지에 연결된 함수를 호출한다. 함수를 호출하면 해당 함수가 사용할 새로운 스택 프레임이 생성된다.
함수 처리는 스택이 다시 텅 빌 때까지 계속된다. 그 후, 큐에 메시지가 남아있으면 같은 방법으로 처리를 계속 진행한다.
Event Loop
는 Call Stack과 Callback Queue를 상태를 계속 감시하며 Call Stack
에 함수들이 존재하지 않는다면 Callback Queue
에 있는 비동기 함수들을 Call Stack
에 밀어 넣는다. 그 후 Call Stack에서 비동기 함수를 실행시키게 된다.
Call Stack(호출 스택) : JavaScript 코드를 실행할 때 함수 호출은 호출 스택에 쌓인다. 호출 스택은 현재 실행 중인 함수의 컨텍스트를 저장하고 관리한다.
Event Queue(이벤트 대기열) : 비동기 작업의 콜백 함수나 이벤트 핸들러는 이벤트 대기열에 추가된다. 이벤트 대기열은 순서대로 이벤트 루프에 의해 처리된다.
Event Loop(이벤트 루프) : 이벤트 루프는 호출 스택이 비어있을 때마다 이벤트 대기열에서 이벤트를 가져와 호출 스택에 넣어 실행한다. 이벤트 루프는 계속해서 호출 스택이 비어질 때까지 이벤트를 처리하고 반복한다.
Microtask Queue(마이크로태스크 대기열) : Promise와 관련된 콜백 함수는 마이크로태스크 대기열에 추가된다. 마이크로태스크 대기열의 작업은 이벤트 루프의 단계 중 호출 스택을 비우고 호출 스택이 비어있을 때 즉시 처리된다. 이는 일반적인 이벤트 대기열의 작업보다 우선시되는 특성을 갖는다.
정리하자면 JavaScript의 이벤트 루프는 JavaScript 엔진이 비동기 이벤트와 콜백 함수를 관리하고 실행하는 방식을 설명한다. 이벤트 루프는 JavaScript가 단일 스레드로 동작하면서도 비동기 작업을 처리할 수 있게 해주는 핵심 메커니즘이며, 브라우저 환경이나 Node.js와 같은 런타임 환경에서 동작한다.