function bar() {
console.log('bar')
}
function foo() {
console.log('foo')
}
function fooBar() {
console.log('fooBar')
setTimeout(bar(), 0)
foo()
}
fooBar()
- 호출 스택:
1. fooBar() [call stack +]
2. fooBar() 내부에 console.log [call stack +]
3. 2. 실행 완료 후 다음 코드 (fooBar() 존재) [call stack -]
4. setTimeout() [call stack +]
5. 4. 타이머 이벤트 실행되며 [task queue +, call stack-]
6. foo() [call stack +]
7. foo() 내부에 console.log [call stack +]
8. 7. 실행 완료 후 다음 코드 (fooBar(), foo() 존재) [call stack -]
9. foo() 제거 (fooBar() 존재) [call stack -]
10. fooBar() 제거 [call stack -]
11. call stack 0
12. task queue 의 bar() [call stack +]
13. bar() 내부에 console.log [call stack +]
14. 13. 실행 완료 후 다음 코드 (bar() 존재) [call stack -]
15. bar() 제거 [call stack -]
- 위의 스택을 보면 setTimeout은 0초뒤에 실행된다는 것을 보장하지 못한다.
- 태스크 큐(Task Queue): 실행해야 할 task의 집합. 이벤트 루프는 task queue를 한개 이상 가지고 있으며, 자료 구조의 큐가 아닌 set 형태를 지니고 있다. 선택된 큐 중에서 실행 가능한 가장 오래된 테스크(비동기 함수의 콜백 함수나 이벤트 핸들러 등)를 가져와야 하기 때문에 FIFO 형식이 아니다.
- 이벤트 루프의 역할은 호출 스택에 실행 중인 코드가 있는지, 태스크 큐에 대기 중인 함수가 있는지 반복해서 확인함. 호출 스택이 비어 있다면 대기 중인 작업이 있는지 확인하고 실행 가능한 오래된 것부터 순차적으로 꺼내와서 실행하며 태스크 큐가 빌 때가지 실행.
- 비동기의 실행은 JS 코드가 동기적으로 실행되는 메인 스레드가 아닌 태스크 큐가 할당되 처리하는 브라우저나 node.js의 역할. 외부 Web API 등은 JS 외부에서 실행되고 콜백이 태스크 큐에 들어감.
| 브라우저에 따른 고려사항과 compile, transpile, interpreter (0) | 2024.09.21 |
|---|---|
| (4) 태스크 큐(task queue) 와 마이크로 태스크 큐(micro task queue) (2) | 2024.09.20 |
| (2) 이벤트 루프 (0) | 2024.09.19 |
| (1) 싱글 스레드와 비동기 통신 (0) | 2024.09.19 |
| 클로저 비용 (0) | 2024.09.19 |