42장 비동기 프로그래밍

해당 포스팅은 위키북스의 모던 자바스크립트 Deep Dive라는 책을 독학하며 기록하는 글입니다.

자바스크립트 엔진은 단 하나의 실행 컨텍스트 스택을 갖는다. 따라서 자바스크립트는 한 번에 하나의 태스크만 실행할 수 있는 싱글 스레드 방식으로 동작하는데, 이 경우 처리에 시간이 걸리는 태스크를 실행하는 경우 블로킹(작업 중단)이 발생한다.

동기와 비동기

동기

앞서 소개처럼 현재 실행 중인 태스크가 종료할 때까지 다음에 실행될 태스크가 대기하는 방식을 동기(synchronous)처리라고 한다. 동기처리는 태스크를 순서대로 하나씩 실행하므로 실행 순서가 보장된다는 장점이 있지만, 앞선 태스크가 종료할 때까지 이후 태스크들이 블로킹되는 단점도 있다.

비동기

반대로 앞선 태스크들이 종료되지 읺은 상태라 해도 다음 태스크를 곧바로 실행하는 방식을 비동기(asynchronous)처리하고 한다. 동기와 비동기의 장점과 단점은 반대이다. 비동기의 경우 앞선 태스크들로 인해 블로킹이 되지 않는 장점이 있지만 실행의 순서를 보장할 수 없다는 점이 단점이다.

setTimeout(() => { console.log("타임아웃"); }, 3000);
console.log("Hi");

위의 코드에서는 3초 뒤 '타임아웃'을 출력하고 'Hi'를 출력하도록 했지만, 실행시키면 'Hi'가 출력되고 3초 뒤에 '타임아웃'이 출력된다. 바로 setTimeout 메서드가 비동기로 작동하기 때문에 3초를 기다리지 않고 바로 다음 태스크인 'Hi'를 출력하는 문을 실행시켰기 때문이다.

대표적으로 타이머 함수인 setTimeout, setInterval과 HTTP요청, 이벤트 핸들러들은 비동기 처리 방식으로 동작한다.

이벤트 루프와 태스크 큐

위에서 말한 것처럼 자바스크립트는 싱글 스레드로 동작하기 때문에 한 번에 하나의 일밖에 처리하지 못한다. 하지만 웹 브라우저를 보면 굉장히 많은 동작들이 동시에 일어나고 있는 것처럼 보이는데 이는 자바스크립트 엔진의 이벤트루프가 동시성을 지원하기 때문이다.

대부분의 자바스크립트 엔진은 콜 스택을 가지고 있다. 콜 스택은 23장 실행 컨텍스트에서 공부한 실행 컨텍스트 스택을 가리키고, 힙은 객체가 저장되는 메모리 공간이다.

자바스크립트 엔진은 이 둘을 통해 태스크가 요청되면 콜 스택에 요청된 작업을 순차적으로 처리하고 처리하면서 필요한 정보나 메모리를 힙을 통해 주고 받는 것이다.

하지만 소스코드의 평가와 실행 외에도 비동기처리를 위해서는 호출 스케줄링을 위한 타이머 등록과 콜백 함수의 등록 등이 필요한데 이는 브라우저나 Node.js에서 처리한다.

브라우저 환경은 태스크 큐와 이벤트 루프를 제공하는데 태스크 큐setTimeout이나 setInterval 메서드와 같은 비동기 함수의 콜백 함수 또는 이벤트 핸들러가 일시적으로 보관되는 영역이다. 이벤트 루프는 콜 스택에 현재 실행중인 실행 컨텍스트가 있는지, 태스크 큐에는 대기중인 함수가 있는지를 반복해서 확인한다. 이 과정에서 콜 스택이 비어 있고 태스크 큐에 대기중인 함수가 있다면 이벤트 루프는 순차적으로 태스크 큐에 대기 중인 함수를 콜 스택으로 이동시켜 실행시킨다.

좋은 웹페이지 즐겨찾기