[JS] 이벤트 루프 (Event Loop)

Kimyujin·2021년 8월 13일
1

자바스크립트 살펴보기

프로세스와 스레드

자바스크립트는 싱글 스레드 언어이다.
싱글 스레드 언어를 이해하기 위해서는 먼저 프로세스와 스레드에 대해 알아야한다. 만약 내가 워드 작업을 하고 있다면, 프로세스와 스레드는 각각 아래와 같은 것을 의미한다.

  • 프로세스(process): 워드라는 큰 작업
  • 스레드(thread): 자동저장, 맞춤법 검사를 하는 작업 (동시)

프로세스와 스레드를 개념적으로는 이렇게 설명할 수 있다.

A라는 것을 실행시키기 전에는 단순히 프로그램으로써 존재합니다. A를 실행시키면, 현재 실행되고 있는 A를 프로세스라고 합니다.
실행 중인 프로그램을 프로세스라고 했는데, 스레드는 그러한 프로세스 내부에서 실행되는 흐름의 단위 입니다. 즉 프로세스의 내부에 있는 개체를 말합니다. 하나의 프로세스에는 최소 하나 이상의 스레드가 존재합니다.

멀티 스레딩

어떤 언어들은 멀티 스레딩을 직접 구현할 수 있는데, (Python, Java, C..)
자바스크립트 자체는 싱글 스레드 언어(하나의 프로세스에 하나의 스레드가 실행되는 것)이다.
하지만 자바스크립트 런타임 환경에서는 멀티 스레딩처럼 동작한다.
이렇게 동작할 수 있게 하는 것이 이벤트 루프(event loop)이며, 이벤트 루프는 자바스크립트의 동시성(concurrency)을 지원한다 라고 말한다.


자바스크립트 런타임 환경

런타임 환경

런타임이란 프로그램이 실행되고 있는 시간, 혹은 실행되고 있는 공간을 말한다. 고로 자바스크립트 런타임 환경이란 자바스크립트가 동작하는 실행 환경을 말한다.

(1) Call Stack과 Task Queue

Call Stack과 Task Queue의 동작 방식을 알면 이벤트 루프는 쉽다.

(1) Call Stack에는 코드들이 실행되면 컨텍스트가 쌓이게 된다.
(2, 3, 4) Web API함수는 컨텍스트가 생성됐다가 pop되고, 브라우저는 이것을 실행하고 만료가 되길 기다린다.
(5) 그리고 나서 Call Stack은 다시 할 일을 한다.
(6)할 일을 하다가, 때가 되면(시간이 다 되거나 응답이 오면) 브라우저는 콜백 함수를 Task Queue에 push한다.
(7, 8) Call Stack이 비워지면 Task Queue에 저장된 콜백 함수들은 하나씩 Call Stack으로 이동되고, 실행된다.

이런 동작을 하는 것이 이벤트 루프 이다.

(2) Microtask Queue

Microtask Queue는 Task Queue처럼 임시 보관소라고 볼 수 있는데, 여기는 아래의 것들이 저장된다.

  • promise의 후속 처리 메서드의 콜백함수
  • mutation observer (Web API)

Task Queue보다 우선순위가 높아서, Microtask Queue에 어떤 함수가 대기하고 있거나 새로 들어온다면 무조건 먼저 Call Stack으로 이동시킨다.

setTimeout(() => console.log("a"), 0); 

Promise.resolve() 
  .then(() => console.log("b")
  .then(() => console.log("c");

이 코드의 실행순서는 어떻게 될까?
아무것도 모른다면 a -> b -> c 의 순서로 출력된다고 생각할 것이다.
실제로는 promise then이 Microtask Queue에 저장되기 때문에 b -> c -> a 의 순서로 출력된다.

Event Loop

결국 이런 동작을 하는 것이 이벤트 루프이다.
만약 이벤트 루프가 없고 이런 동작이 되지 않는다면, 데이터를 가져올 때 30초가 걸린다면 우리는 그냥 30초동안 아무 동작도 할 수 없을 것이다.
이벤트 루프는 싱글 스레드 언어인 자바스크립트를, 런타임 환경에서 멀티 스레딩처럼 동작하게 해준다.

🤔 용어 정리

(1) 프로세스와 스레드

이름설명
프로세스실행되고 있는 프로그램
스레드프로세스 내에서 실행되는 흐름 단위
싱글 스레드하나의 프로세스에 하나의 스레드가 작업 수행
멀티 스레드하나의 프로세스에 둘 이상의 스레드가 동시 작업 수행

(2) 자바스크립트 런타임 환경

이름설명
🅹 Heap객체가 저장되는 메모리 공간
🅹 Call Stack모든 코드가 실행되고 관리되는 영역 (=실행 컨텍스트 스택)
Web APIDOM API, fetch, event listener, setTimeout, setInterval
Task QueueWeb API로부터 전달받은 콜백 함수 임시 보관
Microtask Queuepromise의 후속 처리 메서드의 콜백 함수 보관 (우선순위 1)
Event Loop자바스크립트를 런타임 환경에서 멀티스레딩처럼 동작할 수 있게 해주는 기능

자바스크립트 엔진(🅹): 싱글 스레드로 동작
브라우저: 멀티 스레드로 동작


Reference

TCP School, "멀티 스레드", https://tcpschool.com/java/java_thread_multi
Tigercow, "프로세스와 스레드", https://doorbw.tistory.com/26
yceffort, "nodejs의 멀티쓰레딩", https://yceffort.kr/2021/04/nodejs-multithreading-worker-threads
꿀로그, "Event Loop", https://hsp0418.tistory.com/140?category=408636
realrain, "Javascript 비동기 처리의 이해", https://realrain.net/post/async-await/
드림코딩, [웹 브라우저101] , 이벤트 루프
이응모, [모던 자바스크립트 Deep Dive], 마이크로태스크 큐, 864p

0개의 댓글