자바스크립트는 싱글 스레드인데 어떻게 비동기 작업을 수행할까?

yesung·2024년 5월 1일
1
post-thumbnail

자바스크립트 언어를 사용하는 개발자라면 기본적인 동작원리를 알고 있어야지 더 효율적으로 프로그래밍을 할 수 있다.

왜 비동기 작업이 필요할까?

기본적으로 싱글 스레드 언어이기 때문에 한 번의 하나의 작업만 처리할 수 있다.

예를 들면, 여러 집에서 짜장면을 주문했고 배달원은 먼저 주문한 첫 번째 집에 짜장면을 배달하고 주문 고객이 다 먹을 때까지 대기 후, 그릇을 수거할 때까지를 하나의 작업이라고 가정한다면 이 모든 과정이 끝나야지만 다음 집에 배달을 할 수가 있는 상황이 동기적인 작업이다.

그리고 배달을 하다가 신호가 막히거나 (네트워크 지연) 또는 사고 (에러 발생)가 발생하면 그 상황을 해결할 때까지 다음 작업이 막히게 된다.

이러면 시간적인 측면에서도 오래 걸리고 리소스 활용도가 낮아져서 굉장히 비효율적이다.

하지만 비동기 작업은 어떨까?

작업 완료 여부와 상관 없이 기다리지 않고 다음 작업을 수행할 수 있다. 앞서 설명한 동기 작업과 달리 첫 번째 집에 짜장면을 배달하고 먹을 때까지 기다리지 않고 바로 다음 집으로 배달을 할 수가 있다. 중간에 그릇을 수거하는 작업은 별도로 분리해서 처리를 해도 된다.

주로 네트워크 요청이나 파일 I/O 작업 등이 있고 자바스크립트에서는 콜백 함수 async/awiat 에 의해서 처리 한다.

단, 작업의 순서 처리를 명시적으로 해야 하고 순서가 꼬일 경우에는 에러 확인이 까다로울 우려가 있어서 에러 처리를 명확하게 해주어야 한다.

그래서 비동기 프로그래밍을 하게되면 사용자 경험 (주문 고객 만족도)도 동기적인 작업보다 훨씬 향상되는 장점이 있다.

그러면 비동기 작업은 어떻게 이루어질까?

먼저 프로그램이 실행될 때, 자바스크립트 엔진은 콜 스택을 사용해서 함수 호출을 관리한다.

자바스크립트 엔진은 메모리 힙과 콜 스택으로 구성되어 있고 싱글 스레드이기 때문에 하나의 콜 스택만 가지고 있다.
메모리 힙은 참조 타입 데이터가 저장되고 변수 할당이 일어나는 공간
콜 스택은 가장 마지막에 들어온 함수가 가장 먼저 처리되는 방식 (후입선출)

만약 콜 스택에 비동기 함수가 들어 왔을 경우에는 Web API 에 의해서 처리되고 완료될 경우 콜백 큐에 추가된다.

그리고 이벤트 루프가 콜 스택이 비었는지 확인하고 비어 있을 때 콜백 큐에 대기 중이었던 함수를 순차적으로(선입선출) 콜 스택으로 이동되어 실행시킨다.

실제 코드를 통해 살펴보면

const first = () => {
  console.log('첫 번째 함수');
};

const second = () => {
  console.log('두 번째 함수');
};

first();

setTimeout(() => {
  console.log('세 번째 함수');
}, 3000);

second();
  1. 제일 먼저 first() 함수 콜 스택에 추가
  2. 그 다음 first() 함수 안에 있는 console.log() 가 콜 스택에 쌓이고
  3. 콘솔 창에 첫 번째 함수 출력
  4. 이제 first() 함수는 종료돼서 콜 스택에서 제거되고 setTimeout() 이 콜 스택에 추가
  5. setTimeout() 은 비동기 함수이기 때문에 Web API 에 의해 처리되고 second() 함수와 그 위에 console.log() 콜 스택에 추가
  6. 콘솔 창에 두 번째 함수 출력
  7. second() 함수 종료돼서 콜 스택에서 제거되고 이제 들어올 함수가 없으므로 Web API 에 의해서 3초 동안 처리되고 있었던 setTimeout() 에 콜백 함수를 콜백 큐로 이동
  8. 이벤트 루프는 콜백 큐에 있는 콜백 함수를 콜 스택으로 이동 보내기 위해 콜 스택이 비어 있는지 확인 후 비어 있다면 콜 스택으로 이동 후 실행
  9. console.log() 추가 후 세 번째 함수 출력 후 프로그램 종료

setTimeout()second() 함수가 종료되고 나서 처리되는 게 아니라 이미 Web API 로 넘어 갔을 시점부터 처리되고 있다.

※ 기다리고 처리되는 거면 그거는 비동기가 아니라 동기적인 것.

정리

자바스크립트는 싱글 스레드 방식으로 동작한다.

하지만 싱글 스레드 방식으로 동작하는 것은 자바스크립트 엔진이지 브라우저가 아니다.

브라우저는 멀티 스레드로 동작하고, 이는 Web API, 콜백 큐, 이벤트 루프에 의해서 가능하다.

profile
Frontend Developer

0개의 댓글