Tech is created to fix problem

[Javascript 알짜개념] 콜 스택, 테스크 큐, 이벤트 루프 본문

JS 개념정리

[Javascript 알짜개념] 콜 스택, 테스크 큐, 이벤트 루프

furaha 2023. 8. 6. 16:48
반응형
setTimeout(() => {
	console.log(1)
}, 0)

console.log(2)

// 2
// 1

 

setTimeout 의 지연시간을 0초로 설정했음에도 console 로 2가 먼저 찍힌다. 

왜? setTimeout은 자바스크립트 엔진이 직접 처리할 수 없고, Web APIs 의 도움을 받아 처리해야하기 때문이다

더 자세하게 알기 위해서는 '자바스크립트 이벤트 루프 동작 원리' 에 대해 알아보아야 한다.

 


 

먼저 아래 그림은 브라우저 내부 구성도이다.

 

 

 

맨 위 예제가 동작하는 순서는 아래 1~6 그림 순서대로이다.

 

1 -> 2
3 -> 4
5 -> 6

 

setTimeout() 함수가 Web APIs 를 거치고 내부 콜백함수가 Task Queue 에 쌓인다

console.log(2) 가 콜 스택에 쌓이고 처리된 후

setTimeout() 의 콜백함수와 그안의 내용이 이벤트 루프를 통해 콜 스택에 쌓이고

처리하는 순서는 제일 최근에 쌓인 console.log(1) 이 먼저 처리가 된다

 

자바스크립트가 직접 처리하지 못하는 함수들이 있구나,,

그리고 그 함수들은 콜 스택이 전부 처리된 이후에 나중에 처리가 되는구나,, 

이것이 비동기방식이라는 거구나! 

네트워크 요청, 파일 로딩, 타이머 등은 오래 걸리는 작업인데 동기적으로 처리하게 되면

작업이 완료될 때까지 프로그램이 멈춰버리는 거니까,,,

 


 

하나 하나 개념을 살펴보자

 

Call Stack : 자바스크립트 프로그래밍 언어에서 직접 실행할 수 있는 메모리 구조

Heap : 동적으로 생성된 자바스크립트 객체가 저장되는 공간

Web APIs : 자바스크립트에서 지원하지 않고 브라우저에서 제공하는 것. (AJAX 호출, 타이머 함수, DOM 조작 등)

                    싱글 스레드가 아닌 멀티 스레드로 이루어져 있음

 

Ex.

DOM (동기적 처리)

XMLHttpRequest

Timer API

Console API (동기적 처리)

Canvas API

Geolocation API

 

(꼭 다 비동기 처리는 아니다)

 

그 중 아마 제일 많이 쓰는 것

setTimeout()

setInterval()

.addEventListener()

.then() 

 

예를 들어, setTimeout 비동기 작업은 Web APIs의 한 종류인 Timer API 에서 타이머 스레드를 사용하여 타이머를 수행한다.

마찬가지로, XMLHttpRequest, fetch 와 같은 네트워크 관련 API는 네트워크 스레드를 사용하여 네트워크 요청과 응답을 처리한다.

 

Callback Queue : 비동기적 작업이 완료되면 실행되는 함수들이 대기하는 공간

 

- macrotask(task) queue : setTimeOut, setInterval, fetch, addEventListener 

- microtask queue : promise.then, process.nextTick, MutationObserver (우선순위가 높음)

 

2개의 종류에 따라 콜 스택으로 옮기는 순서가 달라짐.

 

Event Loop

싱글 스레드인 자바스크립트의 작업을 멀티 스레드로 돌려서 작업을 동시에 처리하게 하거나

여러 작업 중 어떤 작업을 우선으로 동작시킬지를 결정하는 세심한 컨트롤을 하는 것이 이벤트 루프!

 

콜스택, 큐, Web APIs 등의 요소들을 모니터링하면서 비동기적으로 실행되는 작업들을 관리하고

순서대로 처리해서 프로그램의 실행 흐름을 제어하는 관리자이다

 

LIFO : Last In, First Out 후입선출

FIFO : First In, First Out 선입선출

 


 

싱글 스레드 언어인 Javascript

 

자바스크립트는 싱글 스레드 언어이다. Java 나 Python 은 멀티 스레드 지원하기에 멀티 작업이 가능하다.

자바스크립트는 일부 기능들을 자체적 엔진이 아니라 브라우저 내부의 멀티 스레드인 Web APIs 에서 비동기 처리를 한다.

즉, 비동기로 동작하는 핵심요소는 자바스크립트 언어가 아니라 브라우저라는 소프트웨어가 가지고 있다고 보면 된다.

Node.js 에서는 libuv 내장 라이브러리가 처리한다.

 

자바스크립트는 왜 싱글 스레드일까?

자바스크립트는 1995년에 넷스케이프에서 웹 브라우저에서 동적인 웹 페이지를 만들기 위해 개발된 스크립트 언어이다. 당시에는 멀티 코어 프로세서가 보편화되지 않았고, 자바스크립트는 웹 브라우저에서 간단한 스크립트 동작을 수행하는 데 주로 사용되었기 때문에 복잡한 병렬 처리를 필요로 하지 않아, 메모리 사용량이 적고, 동기화 문제를 피할 수 있는 싱글 스레드로 구현하였다. 그러나 싱글 스레드는 오래 걸리는 작업이 실행되면 다른 작업들이 대기해야 하므로 응답성이 떨어진다. 또한 CPU 코어를 여러 개 사용할 수 없으므로 성능이 제한된다. 이러한 문제들을 해결하기 위해 언어 자체의 설계를 바꾸는 것 보단, 브라우저의 멀티 스레드를 이용하는 자바스크립트의 비동기 프로그래밍을 지원하는 것이다. 그리고 이 비동기 프로그래밍의 핵심이 이벤트 루프인 것이다. 

 

 

나중에 비동기 본격적으로 배우면

async/await 혹은 then 의 동작원리를 이벤트 루프로 어떻게 돌아가는지 더욱 자세하게 살펴보면 좋을 것 같다는 생각을 했다.

 


 

[참고 링크]

시각화 시킨 사이트 : http://latentflip.com/loupe 

속도 조금 더 느린 사이트 : https://kamronbekshodmonov.github.io/JELoop-Visualizer/

내가 참고한 사이트 : 이벤트 루프 동작 구조 & 원리 끝판왕

 

반응형