Frontend Study - 2/Javascript

Javascript : 동기와 비동기 (1) 자바스크립트 엔진과 Web Api. 비동기와 멀티쓰레드.

갓데미 2022. 9. 5. 23:38

 

동기적 언어 : 한번에 하나의 일을 처리한다.

비동기적인 언어 : 여러가지 일을 동시에 처리한다.

 

자바스크립트는 기본적으로 동기적인 언어이다. 싱글쓰레드로서 한번의 하나의 일만 처리할 수 있다.

한번의 하나의 일만 처리할 수 있기 때문에 a -> b -> c의 명확한 실행 순서가 있고, 순차적이라는 점에서 결과 예측이 용이하다.

하지만 한번에 여러 일을 수행 할 여력이 있음에도 하나씩 처리하는 경우가 생기기 때문에 리소스의 낭비,

즉 비동기적 구조에 비해 효율적으로 동작하지 못할 수 있다.

 

 

 

이런 점을 호스트환경 (Web, Node js) 에서 제공해주는 api들을 통해서 해결할 수 있다. api 를 이용하면 자바스크립트도 여러가지 일을 동시에 처리할 수 있다. 대표적인 비동기 처리 api로 fetch setTimeout, event listener가 있다.

 

fetch의 경우,

fetch는 간단히 말해 자바스크립트에서 서버로 네트워크 요청을 보내고 응답을 받을 수 있도록 도와주는 메소드이다. 

만약 서버에서 받아올 데이터들이 아주 많을 때 fetch 작업을 비동기가 아닌 동기적으로 처리하게 된다면,

fetch가 완료된 이후에 다음 작업이 실행되야 하기 때문에 작업시간이 길어지게 되는 것이다.

 

 

비동기 작업을 위한 web api가 자바스크립트 엔진과 함께 실행되는 과정은 아래와 같다. 

자바스크립트 엔진이 코드를 한 줄씩 읽어나간다.

객체를 생성하는 내용이 있다면 메모리 힙에 객체(자바스크립트에서 모든 함수는 객체이다)가 저장되고,

콜스택에서는 코드 실행에 따라 호출 스택이 쌓인다. 함수의 실행 순서를 기억한다.

이 때 비동기 api를 만난다면, 예를들어 setTimeout 메소드를 읽는다면, 자바스크립트는 브라우저에게 '몇 초 뒤에 여기 적힌 콜백함수를 실행해' 라고 요청을 하게 되는 것. 

브라우저는 요청한 시간이 지난 후에 해당 콜백함수를 Task Queue에 전달한다. 시간을 재는 것이 브라우저에서 비동기적으로 처리되는 것이다.

이벤트 루프가 돌면서 Call Stack과 Task Queue를 감시한다.

콜스택이 비어 있는 타이밍에 Task Queue에 있는 콜백함수를 콜스택에 가져오고, 순서에 맞게 함수가 실행되게 된다.

 

 

여기서 중요한 것은 동기적 언어인 자바스크립트에서 웹 api를 통해 비동기 처리가 가능하다고 해서, 

싱글쓰레드인 자바스크립트가 멀티쓰레드가 되는 것은 아니라는 것이다. 

아래의 그림을 보면 이해가 쉽다. 자세한 설명은 링크 참조

https://stackoverflow.com/questions/748175/asynchronous-vs-synchronous-execution-what-is-the-main-difference/748235#748235

 

 

Synchronous (one thread):

1 thread ->   |<---A---->||<----B---------->||<------C----->|

Synchronous (multi-threaded):

thread A -> |<---A---->|   
                        \  
thread B ------------>   ->|<----B---------->|   
                                              \   
thread C ---------------------------------->   ->|<------C----->| 

Asynchronous (one thread):

         A-Start ------------------------------------------ A-End   
           | B-Start -----------------------------------------|--- B-End   
           |    |      C-Start ------------------- C-End      |      |   
           |    |       |                           |         |      |
           V    V       V                           V         V      V      
1 thread->|<-A-|<--B---|<-C-|-A-|-C-|--A--|-B-|--C-->|---A---->|--B-->| 

Asynchronous (multi-Threaded):

 thread A ->     |<---A---->|
 thread B ----->     |<----B---------->| 
 thread C --------->     |<------C--------->|

 

 

 

참고

https://academy.dream-coding.com/courses/javascript

https://iamsjy17.github.io/javascript/2019/07/20/how-to-works-js.html