Intro
JavaScript에서 동기와 비동기에 대해 알아보기 전에 JavaScript가 어떻게 동작하는지 알아보자.
JavaScript의 엔진은 기본적으로 싱글스레드로 프로그램을 처리한다. 싱글스레드로 처리할 때 실행할 코드를 하나의 Call Stack을 사용하게되는데 스택 자료구조처럼 동작을 한다. 처리할 코드를 Call Stack에 PUSH하고 처리가 완료된 코드는 POP하게된다.
따라서 기본적으로 JavaScript의 엔진은 프로그램을 동기식으로 처리한다. 하지만 JavaScript 엔진 이외에 Web API, Task Queue, Event Loop등이 JavaScript 런타임 환경에서 실행된다. 그리고 각각의 역할은 다음과 같다.
- Web API : 브라우저에서 제공되는 API로 setTimeout, AJAX, DOM 이벤트 등을 처리한다.
- Task Queue : 이벤트 발생 후 실행되어야하는 콜백 함수들이 대기하는 장소이다.
- Event Loop : 이벤트가 발생했을 때 Call Stack이 비어있는지 확인하고 Task Queue에 있는 콜백함수의 실행 순서를 결정한다.
위의 그림에서 일반적인 JavaScript 함수가 실행된다면 Call Stack에 PUSH가 되고 완료가 되었을 때 POP이 될 것이다. 하지만 setTimeout이나 DOM 이벤트 같은 브라우저에서 제공하는 API를 만나면 Web API로 이동 후에 Task Queue에서 대기한다. 이후 이벤트가 발생하고 Call Stack이 비어있다면 Call Stack으로 이동하여 실행된다.
동기와 비동기
동기식 처리 모델은 프로그램의 순서대로 코드를 처리하는 것이다. 클라이언트에서 서버에 데이터를 요청하면 응답이 올 때까지 다음 실행되어야 하는 작업은 Blocking(중단)된다. 이후 응답이 왔을때 다음 작업들을 실행한다.
아래의 코드는 동기식 처리 모델을 보여주는 코드이며 first() -> second() -> third() 순서대로 함수가 실행된다.
function first() {
console.log("1");
second();
}
function second() {
console.log("2");
third();
}
function third() {
console.log("3");
}
first();
JavaScript에서 비동기식 처리 모델은 클라이언트에서 서버에 데이터를 요청했을 때 응답이 오지않더라도 다른 작업을 수행할 수 있다. 여러 개의 작업을 병렬적으로 처리하기 때문에 전체 작업이 완료되는 속도가 빠르다. 다음 코드는 JavaScript에서 setTimeout으로 비동기식으로 프로그램을 처리하는 방법이다.
first()함수가 실행되어 Call Stack에 들어가고 second()함수가 실행된다. 이때 setTimeout을 만나면서 Call Stack으로 들어가는 것이 아니라 Web API로 들어가서 1000ms를 대기한다. 이후 second()가 완료될 때까지 기다리는 것이 아니라 third()를 실행한다. 1000ms 이후에 second()는 Task Queue에 진입하고 Call Stack이 비어있을 때 PUSH되어 함수가 실행된다. 최종적으로 console에 1 -> 3 -> 2 순서대로 숫자가 출력된다.
좀 더 자세히보면 setTimeout에는 익명함수 형식으로 콜백함수가 있으며 setTimeout이 실행될 때 콜백함수가 Web API에서 지정 대기 시간만큼 기다리다가 Task Queue에 들어가게된다.
function first() {
console.log("1");
second();
}
function second() {
setTimeout(function() {
console.log("2");
}, 1000);
third();
}
function third() {
console.log("3");
}
first();
'프로그래밍 > JavaScript' 카테고리의 다른 글
[Vue] 싱글 파일 컴포넌트(SFC) (0) | 2021.05.11 |
---|---|
[Vue] computed와 watch (0) | 2021.05.10 |
[Vue] Vue 인스턴스 (0) | 2021.05.09 |
[Vue] 시작하기 02 (0) | 2021.05.08 |
[Vue] 시작하기 01 (0) | 2021.05.07 |