브라우저 내에는 여러가지의 Event Loop가 있으며, 각 Event Loop들 끼리 협력한다?
TL;DR
- MicroTaskQueue는 우선순위가 높은게 아니다
- Event Loop의 실행 순서가 정해져 있다.
- JS Event Loop는 동시성을 지원한다
- NonBlocking 특징으로 동시에 여러가지의 task 처리
1. JS Event Loop란?
JS Spec이 아니라 HTML Spec이다...
-
자바스크립트의 런타임 모델은 Event Loop 기반이다
-
특징
-
싱글쓰레드이다 (One Thread = One call stack = One thing at a time)
- Render Process의 Main쓰레드가 JS Engine이다
- 하나의 콜스택을 가지고 있다.
- 한번에 하나의 일만 처리 할 수 있다.
-
Queue(Task, MicroTask)를 가지고 있다.
이름만.. Queue ... Set의 형태이다..
- TaskQueue와 MicroTaskQueue는 다르지만, 같은 방법으로 생성된다(참고)
- MicroTaskQueue는 performing a microtask checkpoint를 통해 실행된다.
-
perform a Microtask checkpoint의 초기값을 False
while (microtaskQueue.waitForMessage()) { //P**erform a Microtask checkpoint = true;** microtaskQueue.processNextMessage() }
- MicrotaskQueue가 있다면?
- Perform a Microtask checkpoint = true
- 가장 오래되면서 실행가능한 Microtask를 실행
- MicrotaskQueue가 비워질때까지 반복
- Perform a Microtask checkpoint = false
-
-
FLOW
-
UI or Interaction
-
Call Stack Running OrQueuing Message(Asyncronous Logic)
-
Timer(setTimout/setInterfal)의 경우, 해당 시간이 지나고 난 다음, Queueing 한다.
-
Promise, MutationObserver 경우, MicroTaskQueue로 진입한다.(async는 Promise의 syntactic sugar)
const response = await fetch(…); const json = await response.json(); const foo = JSON.parse(json) // syntactic sugar fetch(…) .then(response => response.json()) .then(json => { const foo = JSON.parse(json); });
-
-
Call Stack Empty (currently running task === null)
-
Perform a microtask checkpoint 실행
- Perform a Microtask checkpoint = true면, MicroTaskQueue 실행
-
TaskQueue 실행
- Task 실행 후, 3번 ~ 5번 반복
-
Update the rendering
-
2. Event Loop는 동시성이다??
JavaScript는 단일 스레드이므로 동시성이 아니다..???
- 동시성(Cuccent) vs 병렬성(Paraller)
- 동시성 : 여러개의 쓰레드를 번갈아 가면서 실행하는것
- 병렬성 : 여러개의 쓰레드를 각 자 실행하는 것
-
JS engine의 특징
-
“Run to Completion”:
- 실행한 함수가 다른 작업에 의해 선점될 일 없고, 다른 모든 코드의 실행이 우선이며, 중단될 일 없다.
- 이러한 특징은 하나의 함수가 너무 크면, UI가 멈추는 일이 있다.
-
“Non Blocking”
- Event 및 CallBack을 이용하여 Blocking 되지않고, 작업을 처리할수 있기 때문!
-
이러한 특징으로 인해 Concurrency(동시성)을 지원한다.
console.log('before') setTimeout(() => { console.log('Inside SetTimeout') }, 3000) console.log('after')
-
3. 용어 설명
1. Stack === Call Stack
- 콜 스택이란 컴퓨터 프로그램에서 현재 실행 중인 서브루틴에 관한 정보를 저장하는 스택 자료구조이다.
- 사용목적
- 현재 실행중인 서브루틴의 실행이 끝났을때, 제어를 반환할 지점을 보관하기 위해
- 서브 루틴별 컨텐스트를 가지고 있으며, 해당 컨텐스트 안에는 실행, 제어, 런타임 스택이 있다.
2. Heap
- 런타임 환경에서 사용되는 변수(reference)의 영역
- 사용자가 관리하는 영역이라, 자유럽게 메모리를 할당/해제 할 수 있으나, 이러한 자유도로 인해 메모리 누수가 생길 영향이 놓다.
3. Queue(Task Queue)
-
메서지의 대기열..?
-
기본적으로 비동기적인 작업을 Task라 부르며, 이러한 Task의 집합을 Task Queue다
setTimeout('메세지', 500) Promise.resolve().then('메세지')
4. 동기 vs 비동기 / Block vs Non-Block
- 동기 vs 비동기 : 함수의 실행결과가 바로 오는냐?(Sync) 안오냐?(Async)
- Block vs Non-Block : 제어권을 뺏기냐?(Block) 안 빼기냐?(NonBlock)
4. 참고
https://html.spec.whatwg.org/multipage/webappapis.html#event-loops
https://ko.wikipedia.org/wiki/콜_스택
https://innolitics.com/articles/javascript-decorators-for-promise-returning-functions/
https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide/In_depth