Seoplee
개발의 섭리, Seoplee의 개발
Seoplee
  • 분류 전체보기 (54)
    • Android (26)
      • Architecture (12)
      • Compose (0)
      • Tips (11)
      • 트러블슈팅 (3)
    • IOS (1)
      • Tips (1)
    • Kotlin (1)
    • Coroutine (3)
      • Flow (3)
    • RxJava (12)
    • CI&CD (1)
    • WEB (8)
    • Network (1)
    • ETC (1)
    • (임시) (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Seoplee

개발의 섭리, Seoplee의 개발

WEB

JavaScript 기본 동작 원리 (with Stack, Queue, Event Loop)

2022. 6. 25. 22:59

JavaScript 기본 동작 원리

01. 자바스크립트는 싱글 쓰레드 언어

자바스크립트는 싱글 쓰레드 언어이다. 자바스크립트는 하나의 Call Stack만을 가지고있기 때문에 Stack에 쌓이는 순서대로 한번에 하나의 명령만 수행한다. Stack이 하나뿐이므로 여러 동작이 같은 Stack에 쌓이고, 하나의 동작이 끝나고 pop이 되어야만 다음 동작을 수행한다.

Stack은 기본적으로 선입후출(First-In-Last-Out)의 구조를 갖는다.

이는 언뜻 자바스크립트에서는 오로지 동기(Synchronous) 처리만 가능하고 비동기(Asynchronous) 처리는 불가능한것으로 보인다. 이렇게되면 시간이 오래 걸리는 작업을 만나게 되면, 그 뒤의 작업들이 Block 되므로 정상적인 어플리케이션의 구현이 불가능하다.

그러나 사실 자바스크립트는 비동기 처리가 가능하다. 자바스크립트를 실행하는 브라우저(JS Engine)가 Wep API라는것을 제공하기 때문이다.

02. Web API

만약 자바스크립트가 setTiemout, EventListener, Ajax 등의 코드를 만나게 되면 바로 Stack에 쌓이는것이 아니라, Web API라는 곳으로 옮겨진다. 그리고 이 Web API에서 코드들을 수행하고, 처리가 끝나면 이를 Callback Queue라고 하는 곳으로 이동시키며, Callback Stack이 비어있으면, Event Loop가 이 Queue에서 함수를 하나씩 꺼내어 Stack에 넣고 실행시킨다.

이 때 Event Loop가 Stack이 비어있는지 주기적으로 확인하는것을 tick 이라고 한다. Queue는 선입 선출 (First-In-First-Out)의 구조를 가지기 때문에, 별도의 처리를 하지 않을 경우 기본적으로 작업이 끝나는 순서대로 Queue에서 꺼내 사용하게 된다.

즉 동작 순서는 다음과 같다.

  1. Call Stack에 Ajax, EventListener등의 함수가 들어온다
  2. 해당 함수를 Web API로 이동시켜서 작업을 수행한다.
  3. 작업이 완료되면 Callback Queue로 이동시킨다.
  4. EventLoop이 Stack이 비어있는지 확인하고(tick), 비어있다면 Stack으로 보낸다.
  5. Call Stack은 이렇게 들어온 함수를 수행한다.

Call Stack에 setTimeout 함수등이 들어오면 직접 수행하지 않고 Web API로 이동시켜서 수행한다.
수행이 끝나면 이를 Queue로 이동시킨다.
Event Loop는 Call Stack이 비어있는지 확인하고, 함수를 Stack으로 보내고, Stack에서 실행한다.

이러한 동작방식이 setTimeout등의 코드가 정확한 delay 이후 실행되지 않는이유가 된다. 3초동안 작업을 수행하였어도, Stack이 비어있지 않다면 EventLoop가 Call Stack으로 보내지 않기 때문이다. 때문에 기본적으로 Stack에 쌓이는 함수에는 너무 오래걸리는 코드, 예를 들어 수많은 중첩 반복문 등을 작성하면 안된다. 이 Stack이 오랫동안 비어있지 않게 되기 때문에 웹 브라우저가 프리징이 일어날 수 있다.

console.log('1');
setTimeout(function() {
    console.log("2");
},0);
console.log("3");

참고로 위 코드같이 setTimeout에 delay할 시간을 0으로 주어도, setTimeout 함수는 무조건 바로 Web API로 옮기기 때문에 위 코드는 "1" -> "3" -> "2" 순서로 로그가 찍히는것을 확인할 수 있다.

 

+) 흔히 비동기작업을 할때 사용하는 Promise 선언자체는 바로 Web API로 이동시키는것이 아니다.

const p = new Promise((resolve, reject) => {
    console.log('1');
    setTimeout(() => {
        console.log('2');
        resolve('3');
    });
});

console.log('4')

p.then((resut) => {
    console.log('result', result);
});

위 코드의 출력 결과는 다음과 같다.

1
4
2
3

Web API로 이동하는 함수는 then 함수이며 이는 promise의 resolve혹은 에러의 경우 reject가 호출되어야 Queue로 이동한다.

03. 결론

자바스크립트는 싱글 스레드만을 지원하므로 기본적으론 동기적으로 동작한다. 그러나 브라우저의 JS Engine은 비동기로 처리해야 하는 작업을 만나게되면, 이 동작은 Web API 라는 별도의 공간에서 실행시키고, Queue로 이동시킨 다음 차례대로 Stack으로 올려보내 함수를 실행함으로써 비동기적인 처리도 할 수 있게 된다.

 

 

 

Referenece

https://youtu.be/v67LloZ1ieI

https://ingg.dev/js-work

https://youtu.be/Z30cbiPLVfE

저작자표시 (새창열림)

'WEB' 카테고리의 다른 글

[React] useState의 동작원리에 관하여  (0) 2022.12.28
next-sitemap을 사용하여 동적 생성 페이지 sitemap 생성하기  (0) 2022.12.19
DOM(Document Object Model)  (0) 2022.06.27
CSS em & rem  (0) 2022.06.26
CORS(Cross-Origin Resource Sharing) 기본  (0) 2022.06.24
    'WEB' 카테고리의 다른 글
    • next-sitemap을 사용하여 동적 생성 페이지 sitemap 생성하기
    • DOM(Document Object Model)
    • CSS em & rem
    • CORS(Cross-Origin Resource Sharing) 기본
    Seoplee
    Seoplee
    개발공부를 하며 기록할만한 것들을 정리해놓은 블로그입니다.

    티스토리툴바