✅ 동기 처리와 비동기 처리
동기와 비동기
- 동기 - 어떤 태스크가 실행 중일 때 종료될 때까지 다음 태스크가 대기하는 방식을 동기 방식이라고 표현한다.
- 비동기 - 현재 실행 중인 태스크가 종료되지 않았음에도 다음 태스크들을 실행하는 방식을 비동기 방식이라고 표현한다.
자바스크립트 엔진
자바스크립트 엔진은 단 하나의 실행 컨텍스트 스택(콜 스택)을 갖는다.
코드가 평가되어 코드의 실행 컨텍스트가 생성되고 하나의 콜 스택에 저장된다. 그리고 LIFO(Last In First Out) 방식으로 실행 컨텍스트들이 실행된다. (최상위에 있는 실행 컨텍스트 = 현재 실행중인 실행 컨텍스트)
이는 곧 하나의 실행 컨텍스트가 팝되어 실행 중일 때, 콜 스택 내부에서 기다리고 있는 실행 컨텍스트들은 실행될 수 없다는 것을 의미하며, 이를 블로킹(= 작업 중단)이 발생했다고 표현한다. 즉, 자바스크립트는 싱글 스레드 방식으로 동작하며 모든 코드들이 동기적으로 동작한다.
그렇다면 대표적인 비동기 동작 함수 setTimeout과 같은 타이머 함수는 어떻게 비동기 처리를 수행할까?
비동기 방식으로 동작하는 것에는 타이머 함수(setTimeout,setInterval), HTTP 요청, 이벤트 핸들러가 있다. (ES6 프로미스의 경우 비동기 방식으로 동작하지만 태스크 큐가 아닌 마이크로 태스크 큐에 저장된다.)
이에 대한 답은 브라우저에 있다. 브라우저는 이벤트 루프를 제공하여 자바스크립트의 동시성을 지원한다.
✅ 이벤트 루프와 태스크 큐
자바스크립트 엔진은 힙과 콜 스택으로 이루어져 있으며, 태스크가 요청되면 콜 스택을 통해서 요청된 작업을 순차적으로 수행한다.
비동기 처리에서 소스코드의 평가와 실행을 제외한 모든 처리는 브라우저(OR Node.js)가 담당한다.
- 콜 스택 - 코드 평가 과정의 결과물인 실행 컨텍스트들이 실행을 위해 저장되는 스택 자료구조.
- 힙 - 객체들이 저장되는 메모리 공간.
- 이벤트 루프 - 콜 스택에 현재 실행 중인 컨텍스트가 있는지? 태스크 큐에 대기 중인 함수가 있는지 반복해서 확인하며 있다면 태스크 큐에서 pop 하여 콜 스택에 push 한다. 즉, 태스크 큐에 일시 보관된 함수들은 비동기 처리 방식으로 동작한다.
- 태스크 큐 - 비동기 함수의 콜백 함수 또는 이벤트 핸들러가 일시적으로 보관되는 큐 자료구조.
- 마이크로 태스크 큐 - ES6 프로미스와 관련된 콜백 함수가 일시적으로 보관되는 큐 자료구조. 태스크 큐 보다 우선순위가 높다.
중요한 점은 싱글 스레드로 동작하는 것은 자바스크립트이며, 브라우저가 아니라는 점이다. 브라우저는 위에서 보다시피 멀티 스레드 방식으로 동작한다.
브라우저는 자바스크립트 엔진 외에도 렌더링 엔진과 Web API를 제공한다. 이는 ECMAScript 사양에 정의된 함수가 아니라 브라우저에서 제공하는 API이며, DOM API와 타이머 함수, HTTP 요청(Ajax)과 같은 비동기 처리를 포함하고 있다.
댓글