상세 컨텐츠

본문 제목

이벤트 루프(event loop), 호출스택과 태스크 큐 / 자바스크립트

언어/Javascript + Typescript

by moonionn 2020. 7. 7. 18:59

본문

이 문서는 추후 업데이트 예정입니다.

 

출처: https://www.javascripttutorial.net/javascript-event-loop/

 

콜 스택(Call Stack)

콜 스택은 프로그램의 진행단계 중 우리의 위치를 나타내는 데이터 구조입니다.

작동되는 순서에 따라 차례대로 콜 스택에 들어가고, 값을 반환하면 콜 스택에서 지워집니다.

자바스크립트는 싱글스레드를 기반으로 하기 때문에 단 한 줄의 콜 스택만이 존재합니다.

 

콜 스택: 예시1

console.log('one');
console.log('two');
console.log('three');

순서에 따른 콜 스택의 변화

  1. console.log('one') 콜 스택에 추가
  2. 'one' 반환 후 콜 스택에서 삭제
  3. console.log('two') 콜 스택에 추가
  4. 'two' 반환 후 콜 스택에서 삭제
  5. console.log('three') 콜 스택에 추가
  6. 'three' 반환 후 콜 스택에서 삭제

 

조금 더 복잡한 코드의 예를 가져와 보았습니다.

 

콜 스택: 예시2

function A(){
  return 'Hello!';
};

function B(){
  return `${A()} everyone!`;
};

B();

순서에 따른 콜 스택의 변화

  1. 먼저 소환된 function B 콜 스택에 추가
  2. function B가 function A를 소환
  3. function A 콜 스택에 추가
  4. function A가 'Hello!' 값 출력 후 콜 스택에서 삭제
  5. function B가 'Hello! everyone!' 출력 후 콜 스택에서 삭제

예시1, 예시2에서 보다시피,

콜 스택은 Last in First out (LIFO) 형식을 취하는 걸 알 수 있습니다.

흥미롭게도, 콜 스택은 유한한 범위를 지니고 있습니다.

너무 많은 작업을 콜 스택에 몰아넣다 보면 오류가 나고 말죠. 예시를 한 번 봅시다.

 

콜 스택: 추가 예시

function foo() {
  foo();
}

foo();

출처: https://blog.sessionstack.com/how-does-javascript-actually-work-part-1-b0bacc073cf

여기서 foo()는 본인이 본인을 호출하는 일종의 재귀함수처럼 작동하고 있는데,

문제는 종료해주는 코드가 없습니다!

이러면 콜 스택에 foo() 함수가 주구장창 쌓이고

콜 스택의 최대 사이즈를 초과하였습니다 라는 에러문구가 뜨게 됩니다.

 

큐(Queue)

일종의 대기열과 같은 개념으로 이해할 수 있습니다.

setTimeout, setInterval, setImmediate 등과 같은 비동기 처리나,

이벤트리스너의 콜백과 같은 처리는 태스크 큐로 들어갑니다.

단순 글 설명보다는 예시를 보며 이해해 봅시다.

 

큐: 예시1

function timeSet(){
  setTimeout(say, 2000);
  console.log('Yee-ha!');
};

function say(){
  console.log('Ya-ho!');
};

timeSet();
  1. function timeSet() 콜스택에 추가
  2. function timeSet()의 setTimeout이 콜스택에 추가
  3. setTimeout 기능이 활성화되면서 web API가 2초짜리 타이머를 생성
  4. setTimeout은 할 일을 다 했으니 콜스택에서 제거
  5. 그 사이 console.log('Yee-ha!')가 콜스택에 추가
  6. 'Yee-ha!' 출력 후 콜스택에서 제거
  7. 2초 후 say()가 큐에 추가, 대기
  8. function timeSet() 콜스택에서 제거
  9. 콜스택이 모두 비워지면 그제서야 큐에서 대기하고 있던 say()가 콜스택에 추가
  10. 'Ya-oh!' 출력
  11. say() 콜스택에서 제거

콜 스택은 단 하나만 존재하는 반면 
큐는 태스크큐, 잡큐, 이벤트큐 등 다양한 큐가 존재합니다.

Last in First out (LIFO)의 콜 스택과 달리

큐는 First in First out (FIFO) 방식을 취합니다.

 

이벤트루프는 그 중간에서 콜 스택이 비었는지,

큐가 비었는지를 수시로 확인하는 역할을 합니다.

콜 스택이 비워져있고 큐에 처리해야 할 작업이 남아 있다면

가장 오랫동안 큐에 머물던 작업을 콜 스택으로 옮깁니다.

콜 스택과 큐가 모두 비워져 있으면 프로그램은 종료됩니다.

 

아래는 이벤트루프의 작동방식을 애니메이션으로 표현한 링크입니다.

백문이 불여일견이죠.

 

http://latentflip.com/loupe/?code=JC5vbignYnV0dG9uJywgJ2NsaWNrJywgZnVuY3Rpb24gb25DbGljaygpIHsKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gdGltZXIoKSB7CiAgICAgICAgY29uc29sZS5sb2coJ1lvdSBjbGlja2VkIHRoZSBidXR0b24hJyk7ICAgIAogICAgfSwgMjAwMCk7Cn0pOwoKY29uc29sZS5sb2coIkhpISIpOwoKc2V0VGltZW91dChmdW5jdGlvbiB0aW1lb3V0KCkgewogICAgY29uc29sZS5sb2coIkNsaWNrIHRoZSBidXR0b24hIik7Cn0sIDUwMDApOwoKY29uc29sZS5sb2coIldlbGNvbWUgdG8gbG91cGUuIik7!!!PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D

 

http://latentflip.com/loupe/?code=JC5vbignYnV0dG9uJywgJ2NsaWNrJywgZnVuY3Rpb24gb25DbGljaygpIHsKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gdGltZXIoKSB7CiAgICAgICAgY29uc29sZS5sb2coJ1lvdSBjbGlja2VkIHRoZSBidXR0b24hJyk7ICAgIAogICAgfSwgMjAwMCk7Cn0pOwoKY29uc29sZS5sb2coIkhpISIpOwoKc2V0VGltZW91dChmdW5jdGlvbiB0aW1lb3V0KCkgewogICAgY29uc29sZS5sb2coIkNsaWNrIHRoZSBidXR0b24hIik7Cn0sIDUwMDApOwoKY29uc29sZS5sb2coIldlbGNvbWUgdG8gbG91cGUuIik7!!!PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D

 

latentflip.com

 

 

출처
https://blog.sessionstack.com/how-does-javascript-actually-work-part-1-b0bacc073cf

 

관련글 더보기

댓글 영역