-
자바스크립트의 이벤트 루프(Event Loop) 알아보기JavaScript 2023. 3. 27. 22:28
자바스크립트에서 자주 접하게 되는 개념인 이벤트 루프에 대해서 알아보고 블로그에 기록을 남기기로 하였다.
자바스크립트가 싱글 스레드인 이유는 콜 스택이 단 하나뿐이기 때문이다.
하지만, 실제 자바스크립트는 비동기적으로 코드가 실행된다.
🍌 하나의 작업이 끝나지 않았어도 다른 작업을 호출할 수 있다.이렇게 자바스크립트가 작동될 수 있는 이유는 이벤트 루프에 있다.
🥕 자바스크립트 엔진 내부에 Memory Heap과 Call Stack이 존재한다.
- 자바스크립트에서 실행이 되야할 함수는 모두 콜 스택에 쌓이게 된다.
- 메모리 힙은 객체가 저장되는 공간으로, 실행 컨텍스트는 힙에 저장된 객체를 참조한다.
🥦 브라우저에 존재하는 Web API는 AJAX나 setTimeout, setInterval 등의 타이머 함수와 DOM, addEventListener로 추가된 이벤트 등의 작업을 처리할 수 있도록 한다.
- 콜 스택에서 비동기 함수 실행되면, Web API로 이동되어 처리된다.
- Web API는 비동기 작업을 처리한 뒤, 콜백 함수를 콜백 큐(테스크 큐)에 push한다.
🌺 Callback Queue (Task Queue)는 Web API에서 넘겨 받은 (비동기적으로 실행된) 콜백 함수를 저장한다.
- 콜백 큐에 쌓인 콜백 함수들은 곧바로 콜 스택으로 갈 수 없다.
- 콜백 함수가 콜백 큐에서 콜 스택으로 이동하기 위해서는 이벤트 루프의 도움이 필요하다.
🍒 Promise를 처리할 때는 마이크로태스크 큐(Microtasks Queue)라는 콜백 큐에 저장되는데, 이는 다른 큐(Macrotask Queue, 매크로태스크 큐) 보다 우선순위가 높다.
- ex) setTimeout보다 await가 항상 더 먼저 처리된다.
마이크로테스크 큐: Promise의 then, catch, finally와 async/await, process.nextTick과 같은 비동기 작업의 콜백이 저장되는 큐이다.
매크로테스크 큐: setTimeout, setInterval, DOM 이벤트 핸들러와 같은 비동기 작업의 콜백이 저장되는 큐이다.
콜 스택(실행 스택)이 완전히 비워지면, 마이크로테스크 큐의 콜백 함수가 실행된다.
그리고 마이크로테스크 큐가 완전히 비게되면 이제 매크로테스크 큐의 함수가 실행된다.
🌵 Event Loop는 Call Stack와 Callback Queue을 살피면서 Call Stack이 비어있을 때만 Callback Queue의 함수를 Call Stack로 이동시킨다.
- 이벤트 루프는 콜 스택이 비어있을 때, 가장 먼저 콜백 큐에 들어온 함수를 콜 스택으로 이동(호출)시킨다.
🥛 이 과정을 tick이라고 한다. 마지막 함수가 종료되면, tick이 끝났다고 한다.
위와 같은 과정들을 통해서, 자바스크립트는 싱글 스레드 언어이지만, 멀티 스레드인 것 처럼 작동할 수 있다.
- 따라서 Web API는 항상 뒤늦게 실행된다.
setTimeout(() => { console.log("0"); }, 0) console.log("1"); console.log("2"); console.log("3"); console.log("4"); console.log("5");위 코드의 실행 순서는 1, 2, 3, 4, 5 그리고 0이다.
0초를 기다리기에 바로 실행될 것 같지만, 그렇지 않다.
콜백 큐에 들어간 console.log("0") 은 콜 스택이 빈 후에야 이벤트 루프에 의해서 콜 스택으로 이동되어지기에 필연적으로 나중에 실행된다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/EventLoop
이벤트 루프 - JavaScript | MDN
JavaScript의 런타임 모델은 코드의 실행, 이벤트의 수집과 처리, 큐에 대기 중인 하위 작업을 처리하는 이벤트 루프에 기반하고 있으며, C 또는 Java 등 다른 언어가 가진 모델과는 상당히 다릅니다.
developer.mozilla.org
'JavaScript' 카테고리의 다른 글
이벤트 버블링(Event Bubbling) 및 이벤트 캡처링(Event Capture)에 대해서 (1) 2023.04.26 브라우저 Scroll Event 사용하기 (0) 2023.04.02 Ajax에 대해서 (비동기적인 웹페이지 구성) (0) 2023.03.17 즉시 실행 함수 (IIFE, Immediately Invoked Function Expression) 간단히 알아보기 (0) 2023.03.16 tailwind css 사용하기 (CRA, Next.js) (0) 2023.03.04