JavaScript | 싱글스레드인 자바스크립트가 비동기 처리를 하는 법

Positive Ko·2021년 3월 1일
2

JavaScript

목록 보기
22/28

자바스크립트 비동기 시리즈
Callback 함수
Promise 개념부터 이해하기 (1/2)
Promise 개념부터 이해하기 (2/2)
비동기의 꽃, Async와 Await
...에 이어지는 글입니다😇

내용 상으론 가장 맨 처음에 작성해야할 것 같은 내용이다.
콜백, Promise, Asnyc, Await을 말하기 이전에,
왜 자바스크립트는 싱글스레드 언어이며 왜 비동기처리를 해주어야 하는지에 대해 정리해보자.

자바스크립트는 싱글스레드 언어이다.

one thread == one call stack == one thing at a time

자바스크립트는 메인 스레드 하나 콜스택 하나를 갖고 있는, 싱글스레드로 동작하는 언어이다.
싱글스레드 언어이기 때문에, 한 번에 하나의 작업만 수행할 수 있다. 다른 작업이 중간에 끼어들 수 없고, 기존에 수행하던 작업이 끝나야 다음 작업을 이어서 실행한다.

만약, 하나의 문서 안에 여러 개의 함수가 있다고 하자.
여러 함수 사이에 동영상을 불러오거나 미디어 파일을 서버로 보내는 등, 덩치가 큰 작업을 해야한다면?
이 함수를 처리하는 시간 동안 다음의 작업들을 동시에 미리 진행하도록 만들어줘야 한다.
(마치 세탁기를 돌려놓고 청소기를 돌리거나 설거지를 하는 것처럼)

이걸 자바스크립트는 어떻게 해결할까?
비동기 처리?
하지만 자바스크립트는 그 자체만으로 비동기 처리를 하지 않는다.
그렇다면 비동기 요청은 어떻게 이뤄지는 것일까?


자바스크립트의 작동 방식

자바스크립트의 런타임은 메모리 힙(memory heap)콜스택(call stack)으로 구성되어 있다.
아래 사진은 V8 엔진의 간략한 모습이다.


메모리 힙: 메모리 할당을 담당.
콜스택: 함수의 호출 순서를 저장. 코드가 호출되면서 실행컨텍스트가 스택으로 쌓이는 곳.

V8(구글의 V8이 가장 유명한 자바스크립트 엔진)과 같은 자바스크립트 엔진은 하나의 콜스택을 사용한다. (하나의 콜스택, 즉 싱글스레드 언어.)
콜스택에는 메인스레드에서 호출되는 함수들이 순차적으로 쌓인다. 이 함수들은 LIFO(Last In First Out) 방식으로 실행되면서 콜스택에서 사라진다.

차곡차곡 콜스택에 쌓이다가 비동기 처리를 하는 함수(e.g. setTimeout())를 만나면 어떻게 될까?

비동기 처리를 하는 함수가 콜스택에 들어오면 바로 Web API로 보내지고 콜스택에서는 사라진다. 비동기 함수는 자바스크립트 엔진을 구동하는 환경인, 브라우저나 Nods.js가 담당한다.

시간이 지난 후 Web API에서 처리가 완료된 비동기 함수는 일이 끝나면 그 결과와 콜백이 callback queue에 추가된다.
그리고 다시 이벤트 루프에 의해 콜스택에 쌓인다.
즉, 브라우저는 콜스택이 비워질 때마다 callback queue에서 가장 오래된 작업을 꺼내와 콜스택에 넣는데 이를 이벤트 루프라고 부른다.

결국 비동기는 브라우저가 하는 것

실제 자바스크립트에는 setTimeout()과 같은 비동기 함수가 포함되어 있지 않다. 싱글스레드인 자바스크립트 엔진만으로는 이 비동기 함수를 처리할 수 없고 비동기 처리를 브라우저에게 위임한다.
자바스크립트가 구동되는 환경은 브라우저 혹은 Node.js이며, 여기에서는 여러 개의 스레드가 사용되기 때문에 자바스크립트에게 스레드를 지원해주기 때문에 가능한 일이다. 그리고 여러 스레드가 존재하는 환경에서 하나의 콜스택을 사용하는 자바스크립트 엔진과 연동하기 위해 사용하는 장치가 바로 이벤트 루프이다.


사진 출처

What the heck is the event loop anyway? | Philip Roberts | JSConf EU
이 전체적인 사이클을 이해하는 데 가장 도움이 되었던 영상이다.
(12:47 부터 보면 됩니다!)






참고자료
https://medium.com/@vdongbin/javascript-%EC%9E%91%EB%8F%99%EC%9B%90%EB%A6%AC-single-thread-event-loop-asynchronous-e47e07b24d1c
https://meetup.toast.com/posts/89
사진 출처

profile
내 이름 고은정, 은을 180deg 돌려 고긍정 🤭

0개의 댓글