-
[JavaScript] 이벤트 루프 (Event Loop)👩🏻💻 정리/JavaScript 2021. 8. 14. 20:32
목차
1. 동시성 모델
2. 이벤트 루프
2.1 자바스크립트 엔진
2.2 Web APIs
2.3 Task Queue
3. 이벤트 루프의 실행 과정
4. 참고 링크
1. 동시성 모델
이벤트 루프에 대해서 알아보기 전에, 우리는 동시성 모델에 대해서 먼저 알아야 한다. 자바스크립트는 이벤트 루프에 기반한 동시성(concurrency) 모델을 가지고 있다.
💡 동시성이란?
실제 물리적으로 동시에 일어나는 것이 아니라, 흐름을 실행시키는 것은 하나지만 작은 타임 슬라이스 단위로 다른 흐름을 돌아가면서 실행시켜서 동시에 일어나는 것처럼 보이게 하는 방식을 말한다.자바스크립트의 큰 특징 중 하나는 '싱글 스레드' 기반의 언어라는 점인데, 스레드가 하나라는 말은 곧 한 번에 하나의 작업만 처리할 수 있다는 뜻이다. 하지만 실제로 자바스크립트가 사용되는 환경을 생각해보면 많은 작업이 동시에 처리되는 걸 볼 수 있다. 예를 들면, 애니메이션 효과를 보여주면서 마우스 입력을 받고, Node.js 기반 웹 서버에서는 동시에 여러 개의 HTTP 요청을 처리하기도 한다. 스레드가 하나인데 어떻게 이런 일이 가능할까? 자바스크립트는 어떻게 동시성을 지원하는 걸까? 🤔
바로 이벤트 루프가 그 일을 가능하게 해준다!
❗ 자바스크립트가 '싱글 스레드' 기반의 언어라는 말은 엄밀히 말하면 '자바스크립트 엔진이 단일 호출 스택을 사용한다'는 관점에서만 사실이다. 실제 자바스크립트가 구동되는 환경(브라우저, Node.js 등)에서는 주로 여러 개의 스레드가 사용되며, 이러한 구동 환경이 단일 호출 스택을 사용하는 자바 스크립트 엔진과 상호 연동하기 위해 사용하는 장치가 바로 '이벤트 루프'인 것이다.
2. 이벤트 루프
이벤트 루프는 이벤트 발생 시 호출할 콜백 함수들을 관리하고, 호출된 콜백 함수의 실행 순서를 결정하는 역할을 담당한다. 노드가 종료될 때까지 이벤트 처리를 위한 작업을 반복하므로 루프(loop)라고 부른다.
이벤트 루프의 실행 과정을 설명하기에 앞서, 우선 사진 속 항목들을 먼저 알아보자!
2.1 자바스크립트 엔진
자바스크립트 엔진은 Heap과 Call Stack으로 구성되어 있다.
Heap은 메모리를 관리하는 곳으로 변수와 객체의 메모리 할당이 이루어진다.
Call Stack은 코드 실행을 관리하며, 코드가 실행될 때 호출 스택이 Stack의 형태로 쌓인다.
💡 Stack(스택)이란?
자료구조 중 하나로, 후입선출(LIFO, Last In First Out)의 룰을 따른다.2.2 Web APIs
Web API는 브라우저에서 자체 지원하는 API이다.
Web API는 DOM이벤트, AJAX, setTimeout 등의 비동기 작업등을 수행하며, Call Stack에서 실행된 비동기 함수는 Web API를 호출하고, Web API는 콜백 함수를 Task Queue에 밀어 넣는다.
2.3 Task Queue
이벤트 발생 후, 타이머나 이벤트 리스너의 콜백 함수가 들어오는 곳이다. 정해진 순서대로 콜백들이 줄을 서 있으므로 Callback Queue라고도 부른다. 콜백은 보통 완료된 순서대로 줄을 서 있지만 특정한 경우에는 순서가 바뀌기도 한다.
3. 이벤트 루프의 실행 과정
아래 코드가 어떻게 Call Stack에 담기고 실행되는지 살펴보자!
console.log('start'); setTimeout(function callback() { console.log('callback'); }, 5000); console.log('end');
1. 먼저 Stack에 Global Execution Context가 쌓인다.
2. 그러고 나서 첫 번째 줄을 지나면서 'start'를 콘솔 창에 찍게 된다.
3. 그다음 setTimeout을 만나게 된다. setTimeout은 브라우저의 timer 기능을 실행하게 된다. setTimeout에 있는 timer는 Web API에서 실행된다.
4. 타이머는 Web API에 있는 채로 Call Stack에서는 다음 코드를 실행하게 된다.
5. 이어 콘솔 창에 'End'를 찍게 된다.
6. Web API에 있던 timer는 5초가 지나면 Task Queue에 콜백 함수를 전달한다.앞서 모든 자바스크립트의 코드는 Call Stack에서 실행된다고 했다.
그렇다면 현재 Task Queue에 있는 콜백 함수를 Call Stack으로 전달해주어야 한다! 여기서 이벤트 루프가 필요한 것!이벤트 루프는 계속해서 Call Stack과 Task Queue를 주시하고 있는데, 언젠가 스크립트에 있는 모든 코드가 실행이 되고 Call Stack은 비게 된다. 이벤트 루프는 Call Stack이 비워진 순간에 바로 Task Queue에서 대기 중이던 콜백 함수를 Call Stack에 전달한다.
그렇게 Call Stack에 들어간 함수는 실행이 되고 나면 또 Call Stack이 비게 되고, Task Queue에 다음에 또 대기 중인 함수가 있었다면 차례로 그 함수를 Call Stack에 전달하는 것이다.
+) setTimeout이 어떻게 동작하는지 알았으니 하나만 더 짚고 넘어가 보자!
setTimeout에 넘겨주는 millisecond 인자는 실제로 delay되는 시간이 아니라, 최소 대기시간을 말하는 것이다.
5초 뒤에 콜백 함수를 실행하라고 코드를 작성했는데, 만약 5초가 지났는데도 Call Stack이 비어있지 않다면 어떻게 될까?🤔
5초가 지났어도 Call Stack이 빌 때까지 콜백 함수는 Task Queue에서 대기할 수밖에 없다!
따라서 우리가 setTimeout에 넘겨준 millisecond 이후에 함수가 실행될 것이라는 보장은 없으며, 이 숫자는 최소 대기시간이 되는 것이다.🔗 이벤트 루프가 실제로 돌아가는 걸 테스트해볼 수 있는 사이트
4. 참고 링크
🔗 MDN 동시성 모델과 이벤트 루프
🔗 자바스크립트와 이벤트 루프
🔗 https://eine.tistory.com/entry/자바스크립트-동시성-모델과-이벤트-루프
🔗 https://velog.io/@thms200/Event-Loop-이벤트-루프
🔗 https://zereight.tistory.com/855'👩🏻💻 정리 > JavaScript' 카테고리의 다른 글
[JavaScript] this (0) 2021.08.26 [JavaScript] 스코프 (Scope)와 클로저 (Closure) (0) 2021.08.25 [JavaScript] 호이스팅 (Hoisting) (0) 2021.08.22 [JavaScript] 실행 컨텍스트 (Execution Context) (6) 2021.08.22 [JavaScript] 프로미스 (feat. 동기/비동기, 콜백 함수, async~await) (0) 2021.08.17