Javascript
- 싱글스레드 기반, Event loop를 기반으로 하는 Node.js
- Javascript engine은 JS를 해석하고 실행하는 엔진(콜 스택과 이벤트 큐가 있는)
Javascript engine과 이벤트 루프
Event Loop
- 아래의 방식으로 이벤트루프가 현재 실행중인 task가 없는지, task queue에 task가 있는지 반복적으로 확인
1
2
3
while(queue.waitForMessage()) {
queue.processNextMessage();
}
Call stack
- JS는 단 하나의 call stack 사용
- 자바스크립트 엔진의 call stack
- 따라서 JS가 실행되는 방식은 Run to completion. 하나의 함수가 실행되면 다른 task는 수행될 수 없다.
- 메서드 실행시 call stack에 새로운 stack frame 생성하고 return시 stack에서 해당 frame을 pop한다.
- 혹은 비동기적인 처리가 필요할 때 pop되고 Web API로
Heap
: 동적으로 생성된 객체(인스턴스)는 힙에 할당.
Microtask queue
- task queue보다 여기를 우선적으로 확인
- mutation observer(?), promise가 여기로 들어감.
- Promise의 핸들러는 항상 이 queue를 통과해야 한다.
- 처리되지 못한 에러: microtask queue가 빈 후 처리하지 못한 error에 대해
unhandledrejection
발생.
- 처리되지 못한 에러: microtask queue가 빈 후 처리하지 못한 error에 대해
Task Queue(event queue)
- JS 런타임환경에는 (비동기적으로)처리해야하는 Task를 임시저장하는 대기 큐가 존재. 그것이 Task queue( == event queue.)
- Call stack이 비어졌을 때 queue에 먼저 들어온 task가 stack으로 들어간다.
- 비동기로 호출되는 함수는 (Web API에서 수행된 후)Task queue에 enqueue된다.
- 여기서 지워지는 타이밍은 stack에서 수행 후 pop 되고 나서.
web API or 백그라운드
- 자바스크립트의 엔진(실제 코드가 수행되는 쓰레드)와는 별도의 쓰레드
Ajax
요청,setTimeout()
, 이벤트 리스너 등록 과 같은 것들이 이 곳에서 수행- Settimeout에서 n초가 다 수행되기 전까지, event handler에서 해당 event가 발생하기 전까지 기다리는 곳
- 이후 발생하거나 완료 되면 task queue(자바스크립트 엔진의 쓰레드)로 보낸다.
queue 우선순위
- micrortask queue -> animation frames -> task queue
- 직접적인 작업들은 Web API에서 처리한다.
- animation frame : 브라우저 랜더링 관련
c. f) 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function aaa() {
setTimeout(() => {
console.log('d');
}, 0);
console.log('c');
}
setTimeout(() => {
console.log('a');
aaa();
}, 0);
Promise.resolve().then(() => {
aaa();
console.log('b');
});
- 출력순서 예상해보기. 답 c b a c d d
Async / Await, microtask
await을 만나면 해당 async 함수 실행이 일시정지되고 async 컨택스트 전체가 microtask queue로 삽입된다. 이 후, await 된 함수가 resolve된 promise를 리턴할 때 까지 지연된다.
1 2 3 4 5 6 7 8 9 10
const hello = () => Promise.resolve('Hello world'); async function myFunc() { console.log('In function!'); const rest = await hello(); console.log(res); } console.log('Before'); myFunc(); console.log('After');
- 결과는 Before -> In function -> After -> One
#### Reference)
https://it-eldorado.tistory.com/86
http://asfirstalways.tistory.com/362
https://it-eldorado.tistory.com/86
http://sculove.github.io/blog/2018/01/18/javascriptflow/
https://kkangdda.tistory.com/77