JAVASCRIPT
Event Loop
자바스크립트는 싱글 스레드로, 한 번에 한 가지 일만 할 수 있다. 일반적으로 이는 큰 문제가 되지 않지만 30초가 걸리는 일을 수행한다고 생각했을 때 이는 30초동안 아무것도 할 수 없는 상태가 된다는 것이다. 다행히, 브라우저는 자바스크립트 엔진에서는 제공하지 않는 Web API (DOM API, setTimeout, HTTP request)를 지원한다. 이러한 Web API들은 비동기, non-block 동작을 만드는데 도움을 준다.
우리가 함수를 실행하면, 그 함수는 call stack에 추가된다. 콜 스택은 자바스크립트 엔진의 한 부분이며, 브라우저에만 한정된 것은 아니다. 이것은 선입후출의 스택으로 함수가 값을 반환하면 그 함수는 스택에서 빠져나와 사라진다.
respond 함수는 setTimeout 함수를 반환한다. setTimeout 함수는 Web API에서 제공하는 함수로, 메인 스레드를 막지 않고 작업을 지연시킬 수 있다. setTimeout 에 전달한 콜백 함수 () => { return 'Hey' } 가 Web API에 추가되고 setTimeout, respond 함수들은 스택에서 빠져나온다.
Web API 안에서, 타이머는 setTimeout 에 전달한 1000ms 동안 실행된다. 콜백은 즉시 호출 스택에 추가되지 않고, 큐에 전달된다.
이 과정은 다소 혼란스러울 수 있다. 1000ms 후에 콜백 함수는 콜 스택이 아닌 큐에 추가된다. 해당 함수는 자신의 차례를 큐에서 기다린다.
콜 스택이 비어있다면, 큐에 대기중인 첫번째 요소가 콜 스택에 추가된다.
마지막으로 콜백 함수가 콜 스택에 추가되고, 호출되고, 값을 반환하고, 스택을 빠져나간다.
마지막으로, 아래의 코드를 실행할 때 콘솔에 어떻게 기록될지 어떤 순서로 실행되고 어떤 일이 발생하는지 알아보자.
const foo = () => console.log("First")
const bar = () => setTimeout(() => console.log("Second"), 500)
const baz = () => console.log("Third")
bar()
foo()
baz()
- bar 함수가 호출되고 setTimeout 을 반환한다.
- setTimeout 에 전달한 callback 함수는 Web API에 추가되고, setTimeout 과 bar 함수는 콜 스택을 빠져나온다.
- timer가 실행되고, 그 동안 foo 함수가 실행되고 'First' 가 기록된다. foo 함수는 undefined를 반환하고, baz 함수가 호출되고 콜백 함수가 큐에 추가된다.
- 'Third' 가 기록되고 event loop 는 콜 스택이 비어있음을 확인하고 콜백 함수를 콜 스택에 추가한다.
- 콜백 함수가 'Second'를 기록한다.
참조
✨♻️ JavaScript Visualized: Event Loop