모던 JS Deep Dive 스터디 2주차: Chapter42. 비동기 프로그래밍

Miseon (MIMI)·2024년 2월 14일
post-thumbnail

🔖 개요

프로그래밍을 하면서, 모든 작업을 순차적으로 실행되도록 하는 것이 최선일까? 자바스크립트 엔진에 의한 실행 컨텍스트와 함께 동기/비동기 처리에 대해 알아보자.

🔖 동기 처리와 비동기 처리

함수 호출 시, 함수 코드가 평가되며 '함수 실행 컨텍스트'가 생성된다. 이는 실행 컨텍스트 스택(콜 스택)에 푸시되고, 함수 코드가 실행된다. 함수가 종료되면 해당 함수의 실행 컨텍스트는 실행 컨텍스트 스택에서 팝되어 제거된다.

const foo = () => {};
const bar = () => {};

foo();
bar();

위 코드의 실행 컨텍스트 스택의 변화를 알아본다면,

... -> 전역 -> foo, 전역 -> 전역 -> bar, 전역 -> 전역 -> ...

이와 같은 형태가 될 것이다. 함수가 호출되면 스택에 푸시되고, 종료되면 팝되는 방식이다.

자바스크립트 엔진은 단 하나의 실행 컨텍스트 스택을 갖는다.

그렇다면, 동시에 2개 이상의 함수를 실행할 수 없다는 것이다. 하나의 함수가 실행 중이면 그 외의 함수들의 실행 컨텍스트는 실행 대기 중인 태스크 상태이다.

이러한 구조를 가지게 되는 이유로는 자바스크립트는 싱글 스레드 방식으로 동작하기 때문이다. 한 번에 하나의 태스크만 처리할 수 있으므로, 시간이 걸리는 태스크를 실행하면 블로킹(작업 중단) 이 발생한다. 대표적인 블로킹 작업으로는 sleep 함수에 의한 지연이 있다.

현재 실행 중인 태스크가 종료될 때까지 다음에 실행될 태스크가 대기하는 방식을 동기 처리라고 한다. 순서대로 태스크를 실행할 수 있지만, 태스크 블로킹의 단점이 있다.

현재 실행 중인 태스크가 종료되지 않더라도 바로 다음 태스크를 실행하는 방법도 있다. 이 방식을 비동기 처리라고 한다. 태스크 블로킹의 걱정이 없지만, 태스크 실행 순서가 보장되지 않는다는 단점이 있다.

🔖 이벤트 루프와 태스크 큐

자바스크립트는 싱글 스레드 방식이다. 하지만, 우리가 브라우저를 사용할 땐 여러 태스크가 동시에 수행되는 것처럼 보인다. 이는 자바스크립트의 동시성을 지원하는 이벤트 루프가 존재하기 때문이다.

구글 V8 자바스크립트 엔진을 비롯한 대부분의 자바스크립트 엔진은 콜 스택, 힙으로 구분할 수 있다.

콜 스택
실행 컨텍스트 스택, 순차 처리객체가 저장되는 동적 메모리 공간

위와 같은 방식으로는 여러 태스크를 동시에 처리할 수 없다. 따라서 비동기 처리에서 소스코드 평가 및 실행을 제외한 모든 처리는 브라우저 또는 Node.js가 담당하게 된다. 이를 위해 브라우저는 태스크 큐와 이벤트 루프를 제공한다.

태스트 큐이벤트 루프
콜백함수 및 이벤트 핸들러 일시 보관용태스크 큐 반복적 확인, 순차적으로 태스크 큐에 대기중인 함수를 콜 스택으로 이동함

콜 스택이 비어있고 태스크 큐에 대기 중인 함수가 있다면,

이벤트 루프는 순차적으로 태스크 큐에 대기 중인 함수를 콜 스택으로 이동시킨다.

이를 통해 태스크 큐에 일시 보관되어 있던 함수들은 비동기 처리 방식으로 동작하게 된다.

📍 자바스크립트 엔진과 브라우저

자바스크립트 엔진은 싱글 스레드 방식으로 동작하지만, 브라우저는 멀티 스레드로 동작하기 때문에 비동기 작업을 수행하는 자바스크립트 코드를 실행할 수 있다.

profile
방황하는 개발자

0개의 댓글