자바스크립트에 대해 깊게 공부하기 위해서는 자바스크립트의 동작원리를 알아야한다.
기본적으로 단일 스레드여서 비동기 작업이 불가능할 것 같지만 전혀 아니다!
그 이유에 대해 알아보자.
• JavaScript 엔진
JavaScript 파일은 컴퓨터가 해석할 수 없으므로 브라우저의 JavaScript 엔진이 해석해준다.
이 때, memory heap과 call stack을 사용해서 JavaScript를 기계어로 변환해준다.
- Memory Heap?
메모리 할당이 일어나는 곳
변수, 함수, 객체 등 모든 메모리 할당은 여기서 발생함
- Call Stack?
call = function 호출
stack = 쌓이는 곳(Last In First Out)
즉, 함수 호출이 쌓이는 곳으로 call stack을 통해 어떤 함수가 실행되고 있는지를 알 수 있음
JavaScript는 single thread 기반 언어 = call stack을 하나만 가지고
스택으로 쌓이기 때문에 최근에 호출된 작업부터 차례대로 실행함
하나의 작업이 끝나면 다음 작업을 실행하고, 하나의 작업이 끝나기 전까지 다른 작업을 실행하지 않음
setTimeout, ajax 요청, 이벤트 리스너와 같은 비동기 함수들을 만나면 Web API에게 위임!
• 웹 브라우저 환경
JavaScript 엔진은 단일 call stack을 사용하여 동기적으로 요청을 처리함
웹 브라우저 환경에서 JavaScript가 비동기적으로 처리할 수 있도록 지원해줌
즉, JavaScript는 JavaScript 엔진을 구동하는 환경인 웹 브라우저나 Node.js에서 비동기적으로 동작함
- Web APIs
Web APIs는 JavaScript 엔진이 아닌 브라우저 환경에 존재하는 것
ajax 요청, setTimeout(), 이벤트 리스너와 같은 비동기 함수들을 처리해줌
- Callback Queue
Web API에서 실행된 것들은 Callback queue로 모임
- Event Loop
Call stack과 Callback queue를 감시
Call stack이 비어 있을때에만 Callback queue에서 Call stack으로 하나씩 올려보냄
- 비동기적으로 수행되는 구조
- 코드가 Call Stack에 쌓인 후, 비동기 함수는 Web API에게 위임
- Web API는 비동기 작업을 수행하고, 콜백 함수를 Callback Queue에 push
- 이벤트 루프는 Call Stack에 비어있을 때, Callback Queue에 대기하고 있던 콜백 함수를 콜스택으로 push합니다.
- 콜스택에 쌓인 콜백 함수가 실행되고, 콜스택에서 pop
아래의 코드를 해석해보자...!
function foo() {
console.log("1");
}
function foo2() {
console.log("2")
}
foo();
setTimeout(function() {
console.log("3");
}, 1000);
foo2();
- foo()가 Call Stack에 쌓인 후, 1 출력 -> Call Stack에서 빠짐
- setTimeout()이 Call Stack으로 들어옴
- 비동기 함수 이므로 Web API에게 위임
- foo2()를 Call Stack으로 불러온 후, 2 출력 -> Call Stack에서 빠짐
- setTimeout()의 설정시간인 2초가 지나면, setTimeout()의 콜백 함수를 Callback Queue로 보냄
- EventLoop가 Call Stak이 비어있는지 확인
- 비어있으므로 EventLoop가 Callback Queue에 있는 콜백 함수를 Call Stack 으로 보낸 후 처리
- 3 출력 후 종료
결론적으로 자바스크립트 엔진은 싱글 스레드이지만,
브라우저가 멀티 스레드이기 때문에 비동기적으로 동작할 수 있는 것이다!
'JavaScript' 카테고리의 다른 글
JavaScript Closure(+실행 컨텍스트와 스코프 체인을 곁들인..) (0) | 2023.05.29 |
---|---|
JavaScript this (0) | 2023.05.28 |
JavaScript DOM (0) | 2023.05.16 |
JavaScript Hoisting(호이스팅) (0) | 2023.05.15 |
JavaScript 비동기 처리 방법(Promise, async, await) (0) | 2023.05.03 |