이벤트 루프(event loop), 호출스택과 태스크 큐 / 자바스크립트
이 문서는 추후 업데이트 예정입니다.
콜 스택(Call Stack)
콜 스택은 프로그램의 진행단계 중 우리의 위치를 나타내는 데이터 구조입니다.
작동되는 순서에 따라 차례대로 콜 스택에 들어가고, 값을 반환하면 콜 스택에서 지워집니다.
자바스크립트는 싱글스레드를 기반으로 하기 때문에 단 한 줄의 콜 스택만이 존재합니다.
콜 스택: 예시1
console.log('one');
console.log('two');
console.log('three');
순서에 따른 콜 스택의 변화
- console.log('one') 콜 스택에 추가
- 'one' 반환 후 콜 스택에서 삭제
- console.log('two') 콜 스택에 추가
- 'two' 반환 후 콜 스택에서 삭제
- console.log('three') 콜 스택에 추가
- 'three' 반환 후 콜 스택에서 삭제
조금 더 복잡한 코드의 예를 가져와 보았습니다.
콜 스택: 예시2
function A(){
return 'Hello!';
};
function B(){
return `${A()} everyone!`;
};
B();
순서에 따른 콜 스택의 변화
- 먼저 소환된 function B 콜 스택에 추가
- function B가 function A를 소환
- function A 콜 스택에 추가
- function A가 'Hello!' 값 출력 후 콜 스택에서 삭제
- function B가 'Hello! everyone!' 출력 후 콜 스택에서 삭제
예시1, 예시2에서 보다시피,
콜 스택은 Last in First out (LIFO) 형식을 취하는 걸 알 수 있습니다.
흥미롭게도, 콜 스택은 유한한 범위를 지니고 있습니다.
너무 많은 작업을 콜 스택에 몰아넣다 보면 오류가 나고 말죠. 예시를 한 번 봅시다.
콜 스택: 추가 예시
function foo() {
foo();
}
foo();
여기서 foo()는 본인이 본인을 호출하는 일종의 재귀함수처럼 작동하고 있는데,
문제는 종료해주는 코드가 없습니다!
이러면 콜 스택에 foo() 함수가 주구장창 쌓이고
콜 스택의 최대 사이즈를 초과하였습니다 라는 에러문구가 뜨게 됩니다.
큐(Queue)
일종의 대기열과 같은 개념으로 이해할 수 있습니다.
setTimeout, setInterval, setImmediate 등과 같은 비동기 처리나,
이벤트리스너의 콜백과 같은 처리는 태스크 큐로 들어갑니다.
단순 글 설명보다는 예시를 보며 이해해 봅시다.
큐: 예시1
function timeSet(){
setTimeout(say, 2000);
console.log('Yee-ha!');
};
function say(){
console.log('Ya-ho!');
};
timeSet();
- function timeSet() 콜스택에 추가
- function timeSet()의 setTimeout이 콜스택에 추가
- setTimeout 기능이 활성화되면서 web API가 2초짜리 타이머를 생성
- setTimeout은 할 일을 다 했으니 콜스택에서 제거
- 그 사이 console.log('Yee-ha!')가 콜스택에 추가
- 'Yee-ha!' 출력 후 콜스택에서 제거
- 2초 후 say()가 큐에 추가, 대기
- function timeSet() 콜스택에서 제거
- 콜스택이 모두 비워지면 그제서야 큐에서 대기하고 있던 say()가 콜스택에 추가
- 'Ya-oh!' 출력
- say() 콜스택에서 제거
콜 스택은 단 하나만 존재하는 반면
큐는 태스크큐, 잡큐, 이벤트큐 등 다양한 큐가 존재합니다.
Last in First out (LIFO)의 콜 스택과 달리
큐는 First in First out (FIFO) 방식을 취합니다.
이벤트루프는 그 중간에서 콜 스택이 비었는지,
큐가 비었는지를 수시로 확인하는 역할을 합니다.
콜 스택이 비워져있고 큐에 처리해야 할 작업이 남아 있다면
가장 오랫동안 큐에 머물던 작업을 콜 스택으로 옮깁니다.
콜 스택과 큐가 모두 비워져 있으면 프로그램은 종료됩니다.
아래는 이벤트루프의 작동방식을 애니메이션으로 표현한 링크입니다.
백문이 불여일견이죠.
http://latentflip.com/loupe/?code=JC5vbignYnV0dG9uJywgJ2NsaWNrJywgZnVuY3Rpb24gb25DbGljaygpIHsKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gdGltZXIoKSB7CiAgICAgICAgY29uc29sZS5sb2coJ1lvdSBjbGlja2VkIHRoZSBidXR0b24hJyk7ICAgIAogICAgfSwgMjAwMCk7Cn0pOwoKY29uc29sZS5sb2coIkhpISIpOwoKc2V0VGltZW91dChmdW5jdGlvbiB0aW1lb3V0KCkgewogICAgY29uc29sZS5sb2coIkNsaWNrIHRoZSBidXR0b24hIik7Cn0sIDUwMDApOwoKY29uc29sZS5sb2coIldlbGNvbWUgdG8gbG91cGUuIik7!!!PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D
latentflip.com
출처
https://blog.sessionstack.com/how-does-javascript-actually-work-part-1-b0bacc073cf