JavaScript는 싱글 스레드 기반 언어로, 하나의 호출 스택(Call Stack)만을 사용합니다.
즉, 한 번에 하나의 작업만 수행할 수 있으며, 기본적으로 동기적으로 동작합니다.
하지만 실제로 JavaScript를 사용할 때 여러 작업이 동시에 처리되는 것처럼 보이는 경우가 있습니다.
예를 들어, 브라우저에서 특정 이벤트가 발생하는 동시에 여러 데이터를 호출하는 상황이 발생할 수 있습니다.
이러한 동작이 가능한 이유는 네트워크 요청과 같은 작업이 비동기적으로 실행되기 때문입니다.
이러한 비동기 작업을 가능하게 하는 핵심 개념이 바로 이벤트 루프(Event Loop)입니다.
앞서 말씀드린 것처럼, JavaScript는 싱글 스레드 기반이기 때문에 한 번에 하나의 작업만 수행할 수 있습니다.
그럼에도 불구하고 여러 작업이 동시에 실행되는 것처럼 보이는 이유는 콜 스택(Call Stack)과 태스크 큐(Task Queue)를 활용하여 비동기 작업을 관리하기 때문입니다.
이 역할을 수행하는 것이 바로 이벤트 루프(Event Loop)입니다.
즉, 자바스크립트가 싱글 쓰레드 환경에서도 비동기적으로 동작할 수 있도록 돕는 매커니즘입니다.

자바스크립크 엔진
- Heap
객체가 저장되는 메모리 공간입니다.
크기가 동적으로 변하는 값들이 저장되며, 실행 컨텍스트에서 참조됩니다.- Call stack
실행 컨텍스트가 쌓이는 스택(Stack) 구조입니다.
함수가 호출되면 실행 컨텍스트가 콜 스택에 추가되고, 실행이 끝나면 제거됩니다.
Web API
- 브라우저 또는 Node.js 환경에서 제공하는 비동기 API입니다.
- 대표적으로 DOM 이벤트, AJAX 요청, setTimeout, setInterval 등이 있습니다.
이벤트 루프
- 콜 스택이 비어 있는 경우, 태스크 큐(Task Queue)에 있는 콜백 함수를 가져와 실행합니다.
- 선입선출(FIFO) 방식으로 태스크를 실행하며, 비동기 처리를 담당하는 핵심 요소입니다.
태스크 큐
- 비동기 함수의 콜백 함수 또는 이벤트 핸들러가 일시적으로 보관되는 공간입니다.
- 태스크 큐는 태스크의 Set(집합)입니다.
- 여러 개의 태스크 큐를 가질 수 있으며, 실행 가능한 태스크 중 가장 오래된 작업을 먼저 실행합니다.
JavaScript는 싱글 스레드 언어이지만, 실행 환경(브라우저, Node.js)은 멀티 스레드를 지원합니다.
따라서 JavaScript 엔진과 실행 환경을 연결하는 역할이 필요하며, 이를 이벤트 루프가 담당합니다.
메인 스레드 역할
메인 스레드는 사이트 코드 실행을 담당하는 스레드이며, 다음과 같은 작업을 수행합니다.
1. 코드 실행
2. 이벤트들을 받고 실행
3. 웹 컨텐츠 렌더링 또는 페인팅
이벤트 루프 종류
1. Window Event Loop (브라우저)
2. Worker Event Loop (웹 워커)
3. Worklet Event Loop (CSS 페인팅 등)
비동기 작업은 태스크 큐(Task Queue)에 저장되며, 이벤트 루프가 이를 순차적으로 처리합니다.
이 태스크 큐는 마이크로 태스크(Microtask)와 매크로 태스크(Macrotask)로 구분됩니다.
이 둘의 차이는 처리할 작업의 우선순위로 마이크로 태스크는 매크로 태스크 보다 우선순위가 높습니다.
API에 따라 마이크로 태스크 큐를 사용하거나, 매크로 태스크 큐를 사용합니다.
매크로 태스크(macrotasks)
DOM 이벤트 콜백, 타이머(setTimeout, setInterval), 스크립트 로딩, requestAnimationFrame 등
마이크로태스크(microtasks)
프로미스(Promises) 핸들러 (then / catch / finally) + await, Object.observe, process (MutationObserver 등)

console.log('시작');
setTimeout(()=> console.log('타이머')); // (A)
Promise.resolve()
.then(()=> console.log('프로미스 1')) // (B)
.then(()=> console.log('프로미스 2')); // (C)
console.log('끝'); // (D)

이벤트 루프와 태스크 큐 (마이크로 태스크, 매크로 태스크)
이벤트 루프와 태스크 큐 (마이크로 태스크, 매크로 태스크)
네트워크 요청이 비동기가 아닌 동기로 이뤄지면?
하나의 작업을 처리하기까지 다른 작업이 멈춰, 엄청 느릴 것
이 문제를 해결하기 위해 비동기 콜백을 사용해 해결
비동기 요청은 Node.js 또는 브라우저에서 처리
node는 libuv 라이브러리로 비동기 IO 지원