비동기적 JavaScript(동작 원리)

이경섭·2022년 4월 6일
0

JavaScript

목록 보기
2/3

자바스크립트의 동기 비동기를 공부하던 중

자바스크립트는 기본적으로 싱글 스레드(single thread)방식으로 동작한다.
따라서 호출 스택(call stack)이 하나라 한번에 하나의 작업만이 가능하다.
(정확한 표현은 "자바스크립트 엔진이 한 번에 하나의 태스크(작업)만을 실행 할 수 있는 싱글스레드 방식으로 동작한다." 인 것 같다.)

라는 내용을 보게 되었다.

비전공자로써 해당하는 내용을 이해는데 참 힘들었고 아직도 완전히 이해하지 못했지만 그래도 기록을 하고 나중에 공부를 통해 추가적인 이해를 정리하기 위해 이렇게 글을 쓴다.


👉 싱글 스레드(single thread)란?

스레드(thread)의 사전적 의미는 실이라는 뜻이다.
따라서 싱글 스레드(single thread)란 한가닥의 실이라는 의미이다.
한 가지 작업을 실행하기 위해 순차적으로 실행한 코드를 실처럼 이어 놓았다고 해서 유래된 이름이다.
싱글 스레드란 하나의 프로그램에서 동시에 하나의 코드만 실행할 수 있다는 뜻이며 코드가 실행되서 끝난 지점과 다음 코드의 시작 지점이 연결된 형태이다.

각 스레드는 한 번에 하나의 작업만 수행할 수 있다.
Task A —> Task B —> Task C
각 작업은 순차적으로 실행된다. (다음 작업을 시작하기 전에 이전 작업을 완료해야한다.)

멀티 스레드를 지원하는 프로그래밍 언어는 여러 코어를 사용하여 여러 작업을 동시에 완료할 수도 있다.
Thread 1 : Task A —> Task B
Thread 2 : Task C —> Task D
동시에 돌릴 수 있는 스레드 수는 컴퓨터에 있는 코어 갯수로 제한된다.

그런데 자바스크립트는 싱글 스레드이다.
코어가 여러 개 있어도 메인 스레드라고 하는 단일 스레드에서만 작업을 한다. 이러한 싱글 스레드는 하나의 힙(heap) 영역과 하나의 콜 스택(call stack)을 가진다.
그래서 자바스크립트는 한번에 하나의 콜 스택(call stack)만을 가진다.
하나의 콜 스택을 가진다는 의미는 한 번에 한 가지 일 밖에 못한다는 의미이다. 앞에 일이 완료 될 때까지 다음 코드는 다른 일은 하지 못하고(이를 블로킹이라한다..) 기다려야 해서 웹 사이트에서 다른일을 할 수 없게 된다.
이렇게 싱글 스레드는 일을 동기적으로 처리한다.

🤔그럼 왜 자바스크립트는 싱글 스레드(single thread)로 동작하게 만들었나??

싱글 스레드와 멀티 스레드를 찾아보면서 들었던 의문이다. 왜 멀티 스레드 방식이 아닌 싱글 스레드 방식으로 동작을 하는가?
자바스크립트는 웹페이지의 보조적인 기능을 수행하기 위해 만든
브라우저에서 동작하는 경량 프로그래밍 언어이다.
만약 자바스크립트가 멀티 스레드로 실행되는 언어였다면 웹페이지에 발생되는 동시성 문제에 대해 해결해야 했다. 실제로 멀티 쓰레드로 구현된 서비스에서는 이 동시성 문제에 대해 정말 많은 신경을 쓴다.
만약 자바스크립트가 멀티 스레드라면 교착 상태와 같은 다중 스레드 환경에서 발생 할 수 있는 복잡한 시나리오를 신경써야하며 이것은 웹페이지의 보조적인 기능을 벗어나 엄청난 오류와 문제를 일으킬 것이다.
(실제 구글의 chrome 브라우저 마저도 기존 웹페이지에서 엄청난 동시성 문제를 일으킬 수 있다는 이유로 단일 웹사이트 페이지의 자바스크립트 코드가 동시에 실행되는 것을 허용하지 않는다.)

👉 그러면 자바스크립트는 어떻게 비동기적으로 실행되는가?

자바스크립트는 위에서 설명했듯이 싱글스레드(single thread) 기반 언어로 하나의 call stack만 가지고 있어 한번에 한가지 일만 수행가능하다. 그런데 실제 브라우저는 Ajax로 데이터를 불러오거나 Mouseover로 이벤트를 처리하면서 애니메이션을 동작시키는 등 이렇게 동시성(Concurrency)을 가지며 비동기적으로 동작한다. 그렇다면 어떻게 자바스크립트는 이러한 동시성을 가지는 비동기적 동작이 가능한 것 인가?

이 의문을 해결하려면 먼저 자바스크립트의 구동환경(런타임)을 이해했어야 했다.


👉 자바스크립트 구동환경(런타임)

위 그림은 브라우저 구동 환경(런타임)을 나타낸다.

자바스크립트의 엔진으로 Memory Heap, Call Stack이 있고
(위에서 잠깐 언급했듯이 자바스크립트는 싱글스레드로 하나 힙과 콜 스택을 가진다. 이게 자바스크립트 엔진을 가르킨다.)

그 외 Web APIs, Callback Queue, Event Loop가 있다.
(자바스크트를 비동기적으로 동작하게 만드는 핵심이다.)


Memory Heap

힙은 변수와 객체에 메모리 할당에 사용되는 비정형 메모리이다.
(아직 잘 이해가 안되었다. 추후에 수정)

Call Stack

컴퓨터 프로그램에서 현재 실행 중인 서브루틴에 관한 정보를 저장하는 스택 자료구조이다.
위의 자바스크립트 엔진에서는 단 하나의 실행 컨텍스트 스택(call stack)을 가지며 이는 함수를 실행할 수 있는 창구가 단 하나이며, 동시에 2개 이상의 함수를 동시에 실행할 수 없다는 것을 의미한다.
이것이 자바스크립트가 "싱글스레드(single thread)로 한번에 한가지 작업 밖에 실행 될 수 없다"는 것의 이유이다.

🤔 스택(stack)이란?
LIFO(last in, first out),선입후출 구조를 가진 선형 자료구조이다.

stack에 대한 자세한 내용은 미약하지만 따로 정리한 글이 있습니다. 혹시나 궁금하신 분은 아래 링크를 확인해주시면 감사하겠습니다.
https://velog.io/@dltjq2323/%EC%8A%A4%ED%83%9DStack

예시)

function a() {
	b();
	console.log("a");
}
>
function b() {
	console.log("b");
}
-> a();

위의 예시를 보면 함수 a가 호출이 되고 해당 작업이 call stack에 쌓이게 된다.
그리고 함수 a의 내부 로직인 함수 b 와 console.log("b")가 호출되어 다시 call stack에 쌓인다.
console.log("b")와 함수 b가 차례대로 call stack을 빠져나가 실행되고 b의 내부로직인 console.log("b")가 다시 call stack에 쌓여 실행된다. 마지막으로 함수 a가 빠져나와 실행되면서 함수 a의 작업이 종료된다.

따라서 호출을 통해 가장 나중에 쌓인 작업부터 차례대로 한번에 하나씩 실행되는 것을 알 수 있다.


Web APIs

웹 브라우저에서 제공하는 API로 AJAX나 Timeout, 이벤트 등의 비동기 실행되는 코드를 가져온다.

Callback Queue

Task Queue라고도 하며 Web API에서 넘겨받은 Callback함수를 저장

🤔 큐(Queue)란?
FIFO(First In First Out),선입선출 구조를 가진 선형 자료이다.

Queue에 대한 자세한 내용은 미약하지만 따로 정리한 글이 있습니다. 혹시나 궁금하신 분은 아래 링크를 확인해주시면 감사하겠습니다.
https://velog.io/@dltjq2323/%ED%81%90Queue

따라서 먼저 들어간 Task(작업)부터 차례로 Event Loop에 의해 call stack으로 넘겨준다.

Event Loop

Call Stack이 비어있는지 확인하고 Task Queue(Callback Queue)의 작업Call Stack으로 옮긴다.



👉JavaScript의 비동기적 처리

위 그림을 보면 설정한 시간 뒤에 출력시키는(비동기적처리 되는) setTimeout()함수가 비동기적 처리를 위해 Web APIs로 가서 callback queue에 담긴다.
callback queue 담긴 작업을 Event loop가 call stack이 비어있는지 확인 후 비어있으면 call stack으로 넣는다.

위의 이미지를 보면 자바스크립트 엔진이 어떻게 비동기적으로 동작하는지 시각적으로 잘 보여준다.

(아래의 사이트와 설명 영상이 있으니 더 자세한 내용이 궁금하신 분은 참고하시길 바랍니다.)
http://latentflip.com/loupe/
https://www.youtube.com/watch?v=8aGhZQkoFbQ&t=1246s

🤨 추가로 찾아봐야하는 부분)
-프로세스와 스레드(봐도 잘 이해가...)
-Memory Heap -> call stack에서 작업이 전달되어 실행되는 곳인 것 같은데... 잘모르겠다. 브라우저의 동작원리를 추가로 알아보고 거기서 자바스크립트가 어떻게 표현되었는지 알면은 이해가 될 것 같다.

  • WEB APIs, Task Queue, event Loop 이 엔진 외부에 존재하는 것은 알지만 정확히 어떤 부분에 있는지 모른다. 보안하자.

비동기처리하는 방법인 callback, promise, asysc & await 등 글 정리


Reference)
모던 자바스크립트
https://chanyeong.com/blog/post/44
https://hanamon.kr/javascript-런타임-작동-방식-비동기와-이벤트-루프/
https://www.youtube.com/watch?v=iks_Xb9DtTM (프로세스와 스레드)
https://www.youtube.com/watch?v=v67LloZ1ieI (애플코딩- 자바스크립트 동작원리)
등등.. (이해하려고 이것저것 다 봐서 잘 기억이... )



처음 작성하는 글이라 나름 노력을 했는데도 부족한 것 같네요.
비전공자라 명칭이나 표현이 부적절 할 수 있습니다.
보시는 분이 있을 지 모르겠지만 댓글로 알려주시면 매우 감사드리고 보는대로 수정하겠습니다.

1차 수정 (22.07.10)

0개의 댓글