Node.js에서의 비동기란?
실행 컨텍스트 스택 (콜 스택)
자바스크립트에서는, 콜 스택에 실행 컨텍스트가 푸쉬되고,
실행이 되어 종료되면 팝되어 제거가 된다.
let a = () => {};
let b = () => {};
a();
b();
위와 같은 코드가 실행되면, 아래의 그림과 같은 스택 순서가 실행된다.
그림에서 볼 수 있듯이, 자바스크립트는 단 하나의 실행 컨텍스트 엔진을 갖고있다.
다시 말해, 함수를 동시에 실행할 수 없고, 하나씩만 실행할 수 있다는 뜻이다.
스택의 가장 상위 요소는 “실행 중인 실행 컨텍스트” 이고, 이것을 제외한 모든 것들은
“실행 대기 중인 태스크” 들이다.
“실행 중인 실행 컨텍스트” 들의 실행이 종료되어 스택에서 팝 되면,
다음 대기 중인 태스크가 실행된다.
이렇듯, 자바스크립트는 한 번에 하나의 태스크만 실행할 수 있는 싱글 스레드
방식으로 동작한다.
동기 처리
우선, 동기 처리 방식을 알아보자.
동기 처리는, 어떤 작업이 이뤄지고 있을 땐 그 뒤의 모든 작업들이 처리되지 못하는 방식이다.
주유기가 하나인 주유소에 차들이 줄지어 서있고,
순서대로 하나뿐인 주유기에서 주유를 한다.
주유를 하던 차가 주유를 끝마치고 나가야만 뒤의 차가 주유를 할 수 있다.
이것을 동기 처리라고 한다.
코드로 살펴보자.
const timeOut = (func, delay) => {
const delayTime = Date.now() + delay;
while (Date.now() < delayTime);
// 현재 시간이 delayTime보다 커질 때까지 계속 반복한다.
func();
// delay 시간만큼 시간이 흐르고 나면 콜백 함수 func를 실행한다.
};
const a = () => {
console.log("a");
};
const b = () => {
console.log("b");
};
timeOut(a, 3000);
// timeOut 함수가 3초 실행된다
b();
setTimeout과 비슷하게 일정 시간 이후 함수가 실행되는 timeOut 함수를 만들어 봤는데,
함수 b는 3초가 지나 함수 a가 실행되고 나서야 실행될 수 있는데, 이것을 블로킹(작업 중단)이라고 하며,
이렇게 실행되는 방식을 동기 처리라고 한다.
동기 처리는 실행의 순서가 보장된다는 장점이 있지만 앞의 태스크가 종료될 때 까지
실행되지 못한다(블로킹)는 단점이 있다.
비동기 처리
이번에는 비동기 처리를 알아보자.
비동기 처리는, 작업들을 동시에 수행하는 것이다.
위의 주유소 예를 다시 보자.
이번에는 주유기가 여러개가 있어서 한대씩 주유하는 것이 아니고,
주유를 하고 싶은 모든 차량들이 각자 주유기에 가서 주유를 할 수 있다.
이것이 비동기 처리이다.
이번에도 코드를 살펴보자.
const a = () => {
console.log("a");
};
const b = () => {
console.log("b");
};
setTimeout(a, 3000);
b();
위와 같이 setTimeout 함수를 사용하게 되면,
3초간 b 함수를 블로킹 하는 것이 아니고,
setTimeout 함수가 실행되고 바로 b 함수가 실행된다.
이것을 비동기 처리라고 한다.
현재 실행중인 태스크가 종료되지 않은 상태여도 블로킹이 발생하지 않고
다음 태스크가 실행되는 장점이 있지만, 실행의 순서가 보장되지 않는다는 단점이 있다.