동기 (Synchoronous, 시간을 맞춤)
비동기 (Asychronous, 시간을 맞추지 않음)
1) 메모리 힙: 메모리 할당이 발생하는 곳 (변수를 정의하면 저장이 되는 창고)
2) 호출 스택: 코드가 실행될 때 스택들이 쌓이게 됨
function B() {
setTimeout(function () {
console.log('B-1...');
}, 1500);
}
function A() {
console.log('A-1...');
B();
console.log('A-2...');
}
A();
Call Stack
1) A()
이 들어온다.
2) A()
가 수행됨에 따라 console.log('A-1...');
가 그 위에 올라온다.
3) console.log('A-1...');
가 실행 완료되면 A()
만 남는다.
4) A()
는 아직 끝나지 않았다. 다음으로 B()
가 그 위에 올라온다.
5) B()
가 호출되면서 setTimeout(function ()
이 올라온다.
6) 🚨 그런데 setTimeout(function ()은 어디론가 가버린다.
7) A()
와 B()
가 남는다.
8) B()
가 끝났다. A()
만 남는다.
9) A()
는 아직 끝나지 않았다. console.log('A-2...');
가 올라온다.
10) console.log('A-2...');
실행이 끝나면 A()도 끝난다.
11) 호출 스택이 완전히 비어있다.
12) setTimeout(function ()
의 console.log('B-1...');
이 들어온다.
13) console.log('B-1...');
이 실행 완료되면 다시 호출스택이 빈다.
🚨 setTimeout의 행방
- 브라우저에는 JS 엔진 외에도 Web API와 Call Queue, Event Loop 등이 존재한다.
- setTimeout(비동기 작업)의 경우 Web API에서 대신 처리해준다.
- seTimeout은 설정한 시간동안 Web APIs에서 기다리고, 완료되면 Callback Queue로 함수가 들어온다. (다시 나갈 준비!)
- Event Loop이 call stack과 callback queue를 계속 주시하고 있다가 call stack이 완전히 비면 먼저 들어온 순서대로 callback queue에 있는 함수들을 call stack에 넣어준다.
- 따라서, setTimeout의 지연 시간이 0이라고 해서 0초후에 실행되는 것을 보장하는 것은 아니다!
JELoop Visualizer
위의 사이트에서 내부에서 진행되는 과정을 시각적으로 확인해볼 수도 있다.
function foo() {
foo();
}
foo();