-
[결국은 자바스크립트]3.싱글스레드 자바스크립트의 비동기처리 및 용어정리front-end/Javascript&Typescript 2023. 7. 4. 15:09
자바스크립트는 싱글스레드 언어로, 한 번에 하나의 작업만 처리할 수 있는 특징을 가지고 있습니다. 이는 자바스크립트 엔진이 하나의 호출 스택(Call Stack)을 사용하여 작업을 처리한다는 것을 의미합니다.
싱글스레드의 주요 특징
- 단일 호출 스택: 자바스크립트 엔진은 하나의 호출 스택을 사용하여 함수의 호출과 실행 순서를 추적합니다. 호출 스택은 함수가 호출될 때 해당 함수의 실행 컨텍스트를 쌓고(pop) 실행이 완료되면 제거합니다. 이를 통해 함수 실행 순서를 관리합니다.
- 차단(Blocked) 방지: 싱글스레드 언어로, 한 번에 하나의 작업만 처리할 수 있기 때문에 작업이 오래 걸리면 다른 작업들이 차단될 수 있습니다. 따라서 긴 작업이 실행되면 브라우저나 애플리케이션의 응답성이 저하될 수 있습니다. 이를 방지하기 위해 자바스크립트는 비동기적인 처리 방식을 사용합니다.
- 비동기 처리: 자바스크립트는 이벤트 루프(Event Loop)와 비동기 콜백 함수를 통해 비차단(non-blocking) 실행 방식을 지원합니다. 비동기 작업은 웹 API와 같은 환경 제공자에 의해 처리되며, 작업이 완료되면 콜백 함수가 호출 스택으로 이동하여 실행됩니다. 이를 통해 다른 작업들을 기다리지 않고 다음 작업을 처리할 수 있습니다.
- 동기적 실행: 싱글스레드이기 때문에 코드는 순차적으로 실행됩니다. 동기적으로 실행되는 코드는 작업이 완료될 때까지 다음 작업으로 넘어가지 않습니다. 이는 코드의 실행 순서와 의도한 순서를 일치시키는데 도움을 줍니다.
싱글스레드로 동작하는 자바스크립트는 비동기 처리를 통해 작업의 차단을 방지하고, 이벤트 루프를 통해 비동기 작업을 관리하여 동시성을 제공합니다. 이를 통해 자바스크립트는 더 나은 응답성과 사용자 경험을 제공할 수 있습니다.
자바스크립트의 메인스레드인 이벤트 루프가 싱글 스레드입니다.
이벤트 루프만 독립적으로 실행되지않고 , 브라우저나 NodeJS 같은 멀티 스레드 환경에서 실행이 됩니다.
자바스크립트 자체는 싱글스레드지만 ,
자바스크립트 런타임 환경은 싱글스레드가 아닙니다.
자바스크립트 런타임 자체에서 비동기 API를 지원하는가?
아닙니다. 정확히는 자바스크립트 엔진을 구동하는 런타임 환경에서 담당, 즉, 브라우저 혹은 Node.js가 담당합니다.
싱글스레드 자바스크립트가 비동기 처리를 가능하게 하는 주요한 이유는 이벤트 루프와 비동기 콜백 함수를 통한 비차단(non-blocking) 실행 방식입니다. 이러한 구조를 통해 자바스크립트는 여러 작업을 동시에 처리하고, 작업이 완료될 때까지 기다리지 않고 다음 작업을 처리할 수 있습니다.

용어설명
스레드 (Thread) :
1.스레드는 프로그램 내에서 동시에 실행되는 실행 흐름의 단위입니다.
2.자바스크립트는 싱글스레드 언어로, 하나의 메인 스레드에서 코드를 순차적으로 실행합니다.
3.하지만 웹 브라우저는 멀티스레드 환경이므로, 웹 API를 통해 비동기 작업이 별도의 스레드에서 처리될 수 있습니다.
4.자바스크립트는 이벤트 루프를 통해 비동기 작업의 완료를 감지하고 결과를 처리하는 방식으로 멀티스레드와 유사한 효과를 얻을 수 있습니다.
콜스택 (Call Stack) :
1.콜 스택은 함수의 호출과 실행 컨텍스트를 추적하는 자료 구조입니다.
2.함수가 호출되면 해당 함수의 실행 컨텍스트가 콜 스택의 맨 위에 푸시(push)됩니다.
3.함수의 실행이 완료되면 해당 실행 컨텍스트는 팝(pop)되어 제거됩니다.
4.콜 스택은 LIFO(Last-In-First-Out) 구조로 동작합니다.
힙(Heap):
1.힙은 동적으로 할당된 메모리의 영역입니다.
2.객체와 변수의 실제 데이터가 저장되는 공간으로, 가비지 컬렉션에 의해 관리됩니다.
3.힙은 콜 스택과는 다르게 구조화되지 않은 메모리 영역이며, 참조를 통해 접근됩니다.
이벤트 루프(Event Loop):
1.이벤트 루프는 비동기적인 작업을 처리하기 위한 메커니즘입니다.
2.호출 스택이 비어있을 때, 이벤트 루프는 태스크 큐(Task Queue)와 마이크로태스크 큐(Microtask Queue)를 확인하여 작업을 호출 스택으로 이동시켜 실행합니다.
3.이벤트 루프는 계속해서 호출 스택을 감시하며, 비동기 작업을 처리할 수 있는 상태를 유지합니다.
이벤트 큐 (Event Queue):
1.이벤트 큐는 비동기 작업의 콜백 함수들이 대기하는 큐입니다.
2.이벤트 루프가 호출 스택이 비어있을 때, 이벤트 큐에 있는 콜백 함수들 중 하나를 호출 스택으로 이동시켜 실행합니다.
3.이벤트 큐는 FIFO(First-In-First-Out) 구조로 동작합니다.
WEB API:
1.웹브라우저환경에서제공되는브라우저 API
2.웹 API는 비동기 작업을 처리하고 태스크 큐에 작업을 넣어주는 역할을 합니다.
3.대표적인 웹 API로는 setTimeout, XMLHttpRequest, fetch, addEventListener 등이 있습니다.
첫번째 예시 (동기 함수만)
console.log(1) console.log(2) console.log(3)아주 간단한 순차적으로 콘솔 로그를 출력하는 함수입니다.
동작을 설명하겠습니다.
1. 초기 상태: 콜스택은 비어있습니다.
2. 함수 호출 및 콜스택 추가 & 제거
console.log(1) 함수 호출 ->console.log(1) 콜스택 최상단에 추가됨. ->
console.log(1) 함수가 실행되어 로그에 1 출력->
console.log(1) 콜스택에서 제거.
console.log(2) 함수 호출 ->
console.log(2) 콜스택 최상단에 추가됨. ->
console.log(2) 함수가 실행되어 로그에 1 출력->
console.log(2) 콜스택에서 제거.
console.log(3) 함수 호출 ->
console.log(3) 콜스택 최상단에 추가됨. ->
console.log(3) 함수가 실행되어 로그에 1 출력->
console.log(3) 콜스택에서 제거.
따라서 위의 코드는 순서대로 1, 2, 3이 차례로 출력되는 것입니다. 각 함수 호출은 콜 스택에 추가되고 실행되며, 실행이 끝나면 콜 스택에서 제거됩니다. 함수 호출은 후입선출(LIFO) 원칙에 따라 처리됩니다.
두번째 예시(비동기 포함)
console.log("첫 번째"); setTimeout(function() { console.log("두 번째"); }, 2000); console.log("세 번째");이 예시에서 "첫 번째"와 "세 번째"는 즉시 실행되지만, "두 번째"는 2초 뒤에 실행됩니다. 이는 setTimeout 함수의 콜백 함수가 비동기적으로 실행되기 때문입니다. 자바스크립트는 setTimeout 함수를 호출하면 해당 작업을 백그라운드로 보내고, 나머지 코드를 계속 실행합니다. 그리고 설정된 시간이 경과하면 이벤트 루프를 통해 백그라운드에 있던 작업을 다시 가져와서 실행합니다.
싱글스레드 자바스크립트는 이러한 방식으로 비동기 작업을 처리하며, 이벤트 루프를 통해 작업을 조율합니다. 이벤트 루프는 호출 스택이 비어있을 때 이벤트 큐에 있는 작업을 호출 스택으로 이동시켜 실행하는 역할을 합니다. 이를 통해 여러 비동기 작업들이 순서대로 실행되고, 메인 스레드가 차단되지 않고 다른 작업을 처리할 수 있습니다.
만약 위 예시의 setTimeOut 부분이 2000ms가 아닌 0 이면 어떻게 실행이 될까요?
console.log("첫 번째"); setTimeout(function() { console.log("두 번째"); }, 0); console.log("세 번째");똑같이 첫번째가 호출되면 콜스택에 추가되어 제거 되고, 그 다음 두번째가 호출되면 콜스택에 추가되어 제거가 되고 이 두번째가 제거가 됐을때, 콜스택이 비어있을때 web API에 의해 처리되고 , setTimeOut의 해당 콜백함수가 태스크 큐로 이동합니다.
호출 스택이 비어있을 때, 이벤트 루프는 태스크 큐를 확인합니다. "두 번째"를 출력하는 콜백 함수가 태스크 큐에 대기하고 있으므로, 이벤트 루프에 의해 호출 스택으로 이동되어 실행됩니다. "두 번째"가 콘솔에 출력되고 실행이 완료되면 해당 실행 컨텍스트가 팝되어 제거됩니다.
Reference:
https://www.youtube.com/watch?v=zi-IG6VHBh8
https://www.youtube.com/watch?v=8aGhZQkoFbQ&t=262s
https://www.youtube.com/watch?v=v67LloZ1ieI
'front-end > Javascript&Typescript' 카테고리의 다른 글
[Javascript] window.postMessage (feat: Web Worker) (0) 2023.07.11 [타입스크립트 Enum] What are you Enum!? (1) 2023.07.08 [결국은 자바스크립트] 2. 클로저와 스코프 Closure & Scope (0) 2023.06.25 [결국은 자바스크립트] 1. 비동기 처리 다시 파헤쳐보기 (0) 2023.06.21 [Typescript] Interface 와 Type 차이를 정확히 알아보자 (0) 2023.05.10