동기식 처리 모델(Synchronous processing model)은 직렬적으로 태스크(task)를 수행한다. 즉, 태스크는 순차적으로 실행되며 어떤 작업이 수행 중이면 다음 작업은 대기하게 된다.
서버에서 데이터를 가져와서 화면에 표시하는 작업을 수행할 때, 서버에 데이터를 요청하고 데이터가 응답될 때까지 이후 태스크들은 블로킹(blocking, 작업 중단)된다.
다음 그림을 보면 쉽게 이해될 것이다.
동기적 처리를 코드로 살펴보자.
function func1() {
console.log('func1');
func2();
}
function func2() {
console.log('func2');
func3();
}
function func3() {
console.log('func3');
}
func1();
출력 결과를 보면
출력 결과는 첫 번째줄 코드, 그다음 코드들이 차례로 출력되었다.
이처럼 코드가 위에서 아래로 내려오며 하나가 끝나면 다음 코드가 실행되는 방식을 비동기적 처리라고 한다.
비동기식 처리 모델(Asynchronous processing model 또는 Non-Blocking processing model)은 병렬적으로 태스크를 수행한다. 즉, 수행중인 태스크가 종료되지 않은 상태여도 다음 태스크는 대기하지 않고 실행된다.
서버에 데이터를 요청한 이후 서버로부터 데이터가 응답될 때까지 대기하지 않고(Non-Blocking) 즉시 다음 태스크를 수행한다. 이후 서버로부터 데이터가 응답되면 이벤트가 발생하고 이벤트 핸들러가 데이터를 가지고 수행할 태스크를 계속해 수행한다.
자바스크립트의 대부분 DOM 이벤트 핸들러와 Timer 함수(setTimeout, setInterval), Ajax 요청은 비동기식 처리 모델로 동작한다.
마찬가지로 그림을 통해 쉽게 이해해보자.
비동기적 처리를 코드로 살펴보자.
function func1() {
console.log('func1');
func2();
}
function func2() {
setTimeout(function() {
console.log('func2');
}, 0);
func3();
}
function func3() {
console.log('func3');
}
func1();
출력 결과는
setTimeout()
메서드의 두 번째 인자는 지연시간을 지정하는데 0이기 때문에 바로 실행될것 같지만, 출력 결과는 func1, func2, func3 아닌 func1, func3, func2가 출력되었다.
그 이유는 setTimeout()
메서드는 비동기적 API 이기 때문이다.
컴퓨터가 다음 코드를 어떻게 실행하는지 알아보면
func1()
을 만나 func1
을 호출하게되면 Call stack에 쌓인다.그리고 콘솔에 fun1을 출력한후 fun2()
을 호출한다.func2
함수가 Call stack에 쌓이고 setTomeout()
가 호출된다. 해당 메서드가 비동기적 메서드임을 파악하고, 이를 비동기를 처리하는 다른 프로그램(Web API)으로 위임한다.func3
을 호출하여 콘솔에 func3을 출력한다.setTimeout()
메서드를 위임받아 처리한 프로그램은 "비동기적 API를 제외한 모든 코드가 실행된 이후" 에 결과를 콘솔에 출력한다. 즉, Web API에서 지연시간만큼 기다리다가 해당 콜백 함수가 이벤트 큐(JavaScript의 비동기 작업을 기다리는 대기열)에 추가되고 Call Stack이 비워졌을 때 다시 Call stack으로 이동되어 실행된다.
📚Reference
동기식 처리 모델 vs 비동기식 처리 모델
동기, 비동기 처리