일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 컴포넌트
- array
- Redux
- 비트 연산자
- Component
- 자바스크립트
- es6
- JavaScript
- til
- localstorage
- JS
- 알고리즘
- 프로그래머스
- 파이어베이스
- 타입스크립트
- 프론트엔드
- v9
- 프리온보딩
- Reducer
- Frontend
- TypeScript
- 리액트
- CORS
- state
- 원티드
- react
- 브라우저
- firebase
- react localStorage
- axios
- Today
- Total
도리쓰에러쓰
[JavaScript] 자바스크립트는 비동기적인데 왜 싱글 스레드일까? 본문
💡 비동기적이란?
먼저 실행된 코드의 작업이 끝나기 전에 더 나중에 실행된 코드의 작업이 끝날 수 있음을 말한다.
즉, 동시성을 가지고 있는 코드들을 의미한다.
자바스크립트 V8 엔진은 싱글 스레드를 가지고 있어서 stack이 하나만 존재한다.
그런데 자바스크립트는 어떻게 비동기적으로 실행되는걸까?
1. 단일 호출 스택(Call Stack)
'자바스크립트 엔진이 싱글 스레드를 가지고 있다'는 의미를 해석해보자.
자바스크립트 엔진은 하나의 Memory Heap과 단일 호출 스택(Call Stack)을 가지고 있다.
- Memory Heap: 메모리 할당이 일어나는 곳
- 단일 호출 스택(Call Stack): 코드 실행에 따라 호출 스택이 쌓이는 곳
이 말은 즉슨, 엔진 구조 상 한번에 하나의 함수만 동기적으로 실행 가능하다는 것이다.
하나의 메인 스레드에서 호출되는 함수들이 Call Stack에 쌓일 것이고,
이 함수들은 LIFO(Last In First Out) 방식으로 실행된다.
그런데 어떻게 비동기적으로 작동하는 것일까?
2. 자바스크립트 런타임
위 그림처럼 자바스크립트 엔진 밖에서도 자바스크립트 실행에 관여하는 요소들이 존재한다.
바로 Web API, Event Loop, Callback Queue이다.
- Web API: 브라우저에서 제공되는 API이며, Ajax나 Timeout 등의 비동기 작업 실행
- Callback Queue(=Task Queue): Web API에서 넘겨받은 콜백함수 저장
- Event Loop: Call Stack이 비어있다면 Task Queue의 작업을 Call Stack으로 옮긴다.
아래 예제를 보며 동작하는 과정에 대해 자세히 알아보자.
setTimeOut(() => console.log('bye'));
console.log('hi');
// 출력
// 'hi'
// 'bye'
1. setTimeout 함수가 실행되고 Call Stack에 setTimeout 함수가 추가된다.
2. setTimeout 함수는 Web API가 Timeout 작업을 요청한 시간이 지나면 Task Queue에 인자로 받은 콜백함수를 전달한다.
3. 두번째 라인에 작성한 console.log('hi')가 Call Stack에 추가된다.
4. Call Stack의 console.log가 실행되며 콘솔에 'hi'가 출력된다.
📌 이 때 자바스크립트의 Event Loop는 Call Stack이 비어있는지 항상 확인하는데 방금 console.log가 실행되고 Call Stack이 비워진 것을 확인한다.
5. Call Stack이 비워진 것을 확인한 Event Loop는 Task Queue에 있던 콜백함수를 Call Stack으로 옮겨 작업을 수행한다.
6. 콘솔에 'bye'가 추가로 출력된다.
7. 모든 작업이 끝나게 되면 Call Stack과 Task Queue가 비워진다.
🔽 자신이 짠 코드가 어떻게 실행되고 있는지 확인하고 싶다면 아래 사이트를 참고하자.
(Call Stack, Web API, Task Queue, Event Loop이 어떻게 상호작용 하는지 애니메이션으로 보여주는 사이트)
http://latentflip.com/loupe/?code=JC5vbignYnV0dG9uJywgJ2NsaWNrJywgZnVuY3Rpb24gb25DbGljaygpIHsKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gdGltZXIoKSB7CiAgICAgICAgY29uc29sZS5sb2coJ1lvdSBjbGlja2VkIHRoZSBidXR0b24hJyk7ICAgIAogICAgfSwgMjAwMCk7Cn0pOwoKY29uc29sZS5sb2coIkhpISIpOwoKc2V0VGltZW91dChmdW5jdGlvbiB0aW1lb3V0KCkgewogICAgY29uc29sZS5sb2coIkNsaWNrIHRoZSBidXR0b24hIik7Cn0sIDUwMDApOwoKY29uc29sZS5sb2coIldlbGNvbWUgdG8gbG91cGUuIik7!!!PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D
latentflip.com
📌 이미지 출처
캡틴판교 (https://joshua1988.github.io/web-development/translation/javascript/how-js-works-inside-engine/)
'JavaScript > JS' 카테고리의 다른 글
[JavaScript] 배열 요소를 추가하고 싶을 때 어떤 방법이 좋을까? (0) | 2022.11.10 |
---|---|
[JavaScript] 객체에서 key 하나 깔끔하게 지우는 방법 (0) | 2022.11.03 |
[JavaScript] 자바스크립트에서의 비동기 처리 async - await (0) | 2022.08.16 |
[JavaScript] 자바스크립트에서의 Promise (0) | 2022.08.15 |
[JavaScript] 실행 컨텍스트(Execution Context)란? (0) | 2022.08.10 |