TIL | JavaScript (Event Loop, Web API, Task Queue, Call Stack)

peaceminusone·2021년 12월 12일
0

TIL | JavaScript

목록 보기
2/3

📱사전 워밍업 지식

  • call stack : 현재 실행 중인 함수의 정보를 저장하고 있는 메모리 공간
  • web API : 브라우저가 제공하는 API, setTimeout() alert() 등을 담당
  • task queue : 실행이 필요한 작업 아이템을 지니고 있는 큐
  • event loop : call stack이 비어있는지 확인하고, task queue에 있는 아이템을 call stack에 추가한다

❓ Java Script는 싱글 스레드인데, 왜 멀티 스레드가 가능할까?

자바스크립는 싱글스레드 언어이다. 즉, 멀티 태스킹이 안되며 동시에 한 가지 일만 처리 가능하다는 것이다. 자바스크립트 엔진은 일반적으로 하나의 call stack을 갖는다. call stack실행시킬 함수의 정보를 저장하는 메모리 공간이다. stack의 특징은 다음과 같다. 첫번째로는 FIFO 구조(FIFO, First In First Out), 두번째로는 한 쪽에서만 자료에 접근 가능하다. 즉 실행할 서브루틴(함수)에 접근 지점이 하나(스택의 마지막 요소)이기 때문에 자바스크립트는 동시에 처리 할수 있는 일이 하나이다. (싱글 스레드의 주 특징)

그렇다면 우리가 사용하는 웹브라우저도 싱글스레드처럼 동작하는가? 그렇지 않다. 멀티 태스킹이 가능하며 그 말인 즉슨, 멀티 스레드가 가능하다. 예시로, 페이스북에 친구 추가를 하는 동안에도 우리가 재생한 동영상은 멈추지 않고 잘만 돌아간다. 프로필 사진을 보면서 댓글을 달아도 프로필 사진은 그대로 유지되있다. 어째서 멀티 스레드가 동작하는 것일까? 간단한 이유이다. 자바스크립트는 싱글스레드이지만 그것이 동작하고 있는 브라우저는 멀티스레드이기 때문이다.


⚙️ Event Loop, Web API, Task Queue

브라우저라는 환경에는 자바스크립트 엔진call stack 외에, web APIevent loop 그리고 task queue가 있다. 이러한 요소들로 인해 JavaScript와 달리 브라우저에서 비동기 처리가 가능하다.

Web API

Web API 는 브라우저에서 제공되는 API로, 비동기 작업을 담당한다. 예시로써 setTimeout Web APIsetTimeout의 딜레이(기다리는 시간)을 받고, 시간이 지나면 callback 함수를 task queue에 전달한다.

예시 함수 (setTimeout)

function cheese() {
  console.log("안녕⚡️");
  setTimeout(() => {
    console.log("나는❓");
  }, 0);
  console.log("YK야");
}
cheese();

실행 결과

안녕⚡️
YK야
나는❓

Task Queue

Task QueueWeb API에서 넘겨받은 Callback 함수를 큐 형태로 저장한다.

Event Loop

Event Loopcall stack이 비어있는지 확인하고, call stack이 비어 있다면 task queue에 있는 함수를 call stack으로 넘겨준다.

=> 예시 코드 결과 setTimeout의 시간이 0임에도 "YK야"의 문장이 더 빨리 나왔습니다.
위 부분은 다음에서 설명하겠습니다.


  1. 브라우저가 cheese() 함수를 call stack에 전달한다
    console.log("안녕⚡️")이 call stack에 추가 된다
    event loopcall stack을 확인한다, call stack은 비어있지 않다
  1. 콘솔 창에 "안녕⚡️"이 찍히고 call stack에서 console.log("안녕⚡️")이 제거 된다
  2. setTimeout(..)call stack에 추가 된다
  3. event loopcall stack을 확인한다, call stack은 비어있지 않다
  1. web API가 타이머를 시작한다
  2. setTimeout(..)call stack에서 제가 된다
  3. console.log("YK야")가 call stack에 추가 된다
  4. 콘솔 창에 "YK야" 가 찍히고 call stack에서 console.log("YK야")가 제거 된다
  5. cheese()안의 모든 명령이 처리되어 cheese()가 call stack에서 제거 된다
  6. setTimeout(..)의 타이머가 종료되고, console.log("나는❓")라는 콜백이 task queue에 추가 된다.
  7. event loopcall stack을 확인한다, call stack은 비어있다!
  8. event looptask queue에 있는 console.log("나는❓")라는 콜백을 call stack에 전달 한다
  9. 콘솔 창에 나는❓가 찍히고 call stack에서 console.log("나는❓")가 제거 된다

🌈 시각화 자료

profile
넘어져도 일어나서 나아가는 개발자의 삶을 염원합니다.

0개의 댓글