본문 바로가기

JS, TS

js는 단일 쓰레드잖아..!!!!!!

js는 단일 쓰레드(one thing at a time)이다

그래서 한번에 한가지 코드 밖에 실행하지 못한다 하지만 우리는 js로 비동기 코드를 짜고 실행을 시킨다

js는 한번에 한가지 코드 밖에 실행을 시키지 못하는데 어떻게 비동기 코드를 실행시키고 병렬적으로 작동을 하게 만드는것일까?

js 동작과정을 살펴보면 알수 있다 한번 알아보자!

v8 엔진

자바스크립트를 실행시키는 v8엔진의 구조를 한번 봐보자

Memory Heap(메모리 힙) - 메모리 할당이 일어나는 곳이다 (참조 타입)

Call Stack(콜 스택) - 실행시키는 코드가 쌓이고 삭제되는 곳이다

 

call stack

위에 말한 설명이 잘이해가 안될수 있으니 코드를 보면서 알아보자

const multiply = (a, b) => a * b;

const square = (n) => multiply(n, n);

const printSquare = (n) => {
  const squared = square(n);
  console.log(squared);
};

printSquare(5);

사진과 같이 코드가 stack push되고 return을 하면 pop이 되는 식이다

 

비동기

위에서 말한 call stack 실행과정은 동기 코드일때에만 적용이 된다 

비동기 코드는 브라우저에서 제공하는 event loop, callback queue, web api 들을 통해 동작한다

console.log("tistory");

setTimeout(() => {
  console.log("비동기");
}, 5000);

console.log("gaoooon");

 

위의 코드를 보면 "tistory", "gaoooon", "비동기" 순서로 console.log가 찍힐것이다 한번 알아보자

call stack에서 setTimeout과 같은 비동기 함수를 만나면 web api로 보내고 stack에서 pop한다

그리고 web api에서 5초가 지나면 callback queue로 setTimeout이 받은 callback 함수를 보내고

callback queue에서 대기 하고 있다가 event loop가 stack에 아무것도 없는것을 확인하면 callback queue에 있는 callback 함수를 stack에 넣어 console.log("비동기")를 출력한다

 

이런식으로 작동한다

말과 그림으로만 설명하려고 하니 어려운거 같다

 

추가로 렌더링도 render queue가 있는데 callback queue처럼 call stack에 아무것도 없어야 렌더링 된다

예시로 내가 최근에 scroll event에 따른 조건부 렌더링을 하는 코드를 짰는데 scroll을 할때마다 callback이 생기므로 callback queue에 enqueue 되어 stack이 빌때마다 event loop가 할당 할것이다 그렇다면 렌더링에도 문제가 생길것이다

 

그래서 throttle이다 debounce 기법을 사용하여 event를 줄여 최적화 시키는것이다

 

마무리

이번에는 js 동작과정을 알아보았는데 설명하기 어려운 개념이라고 생각한다

잘설명할수 있을때까지 정리를 해봐야 겠다고 생각한다

 

 

참고

https://www.youtube.com/watch?v=8aGhZQkoFbQ

728x90