비동기 프로그래밍

김동현·2021년 9월 6일
0

JavaScript

목록 보기
26/32
post-thumbnail

동기 처리와 비동기 처리

함수가 호출되면 함수 평가 과정에서 생성된 함수 실행 컨텍스트가 실행 컨텍스트 스택(콜 스택)에 푸시되고 함수가 실행됩니다. 즉, 실행 컨텍스트 스택에 푸시된다는 것은 함수 실행의 시작을 의미합니다.
함수가 호출된 순서대로 실행되는 이유는 함수가 호출된 순서대로 콜 스택에 함수 실행 컨텍스트가 푸시되기 때문입니다. 🔑 즉, 콜 스택은 함수의 실행 순서를 관리하는 스택 자료구조 입니다.

자바스크립트 엔진은 단 하나의 실행 컨텍스트 스택을 갖고 있습니다. 즉, 자바스크립트 엔진은 단 하나의 함수만을 실행할 수 있으며 동시에 여러 개의 함수를 실행할 수 없다는 것을 의미합니다.
🔑 이처럼 자바스크립트 엔진은 싱글 스레드 방식으로 동작하여, 한 번에 하나의 태스크만 실행할 수 있습니다. 이는 처리 시간이 오래 걸리는 태스크를 실행하는 경우 블로킹이 발생할 수 있습니다.

🚒 현재 실행 중인 태스크가 종료할 때까지 다음 실행될 태스크가 대기하는 방식을 동기 처리 방식이라고 합니다. 동기 처리 방식은 태스크를 순서대로 하나씩 처리하므로 순서가 보장된다는 장점이 있지만 블로킹이 발생할 수 있다는 단점을 갖고 있습니다.

🚎 반면에 현재 실행 중인 태스크가 종료되지 않아도 다음 태스크를 실행하는 방식을 비동기 처리 방식이라고 합니다. 비동기 처리 방식은 블로킹이 발생하지 않는다는 장점이 있지만, 처리 순서가 보장되지 않는다는 단점이 존재합니다.

비동기 처리를 수행하는 비동기 함수는 전통적으로 콜백 패턴을 사용합니다. 비동기 처리를 위한 콜백 패턴은 콜백 헬을 발생시켜 가독성을 떨어뜨리고, 비동기 처리 중에 발생한 에러 처리가 곤란하며, 여러 개의 비동기 처리를 한 번에 처리하는 데도 한계가 존재합니다.

🔑 타이머 함수인 setTimeoout, setInterval, HTTP 통신(Ajax), 이벤트 핸들러는 모두 비동기 처리 방식으로 동작한다. 비동기 처리는 이벤트 루프와 태스크 큐와 깊은 관계가 존재한다.

이벤트 루프와 태스크 큐

자바스크립트 엔진은 싱글 스레드 방식으로 동작하므로 한 번에 한 개의 함수만을 실행할 수 있습니다. 하지만 브라우저에서 동작하는 것을 살펴보면 많은 것들이 동시에 처리되는 것 처럼 보여집니다. 예를 들어 HTML 요소가 애니메이션 효과를 통해 움직이면서 이벤트를 처리하기도하고, HTTP 요청을 통해 서버로부터 데이터를 가져오면서 렌더링하기도 합니다. 이처럼 자바스크립트의 동시성을 지원하는 것이 바로 이벤트 루프입니다.이벤트 루프는 브라우저에 내장되어 있는 기능중 하나입니다.

자바스크립트 엔진은 크게 2개의 영역으로 구분할 수 있습니다.

  1. 🍏 콜 스택 : 함수가 호출되면 생성되는 함수 실행 컨텍스트가 실행 컨텍스트 스택에 푸시됩니다. 이때 실행 컨텍스트 스택이 바로 콜 스택입니다.
    함수를 호출하면 함수 실행 컨텍스트가 순차적으로 콜 스택에 푸시되어 순차적으로 실행됩니다. 자바스크립트 엔진은 단 하나의 콜 스택을 사용하기 때문에 현재 실행 중인 실행컨텍스트가 종료되기 전까지 다른 어떤 태스크도 실행하지 않습니다.

  2. 🥑 힙 : 힙은 객체가 저장되는 메모리 공간이다. 메모리에 값을 저장하려면 먼저 메모리 공간의 크기를 결정해야 하는데 객체는 원시 값과는 달리 크기가 정해져 있지 않기 때문에 런타임에 동적으로 결정해야 한다. 따라서 힙은 구조화되어 있지 않다는 것이 특징입니다.

이처럼 콜 스택과 힙으로 구성된 자바스크립트 엔진은 태스크가 요청이 되면 콜 스택을 통해 요청된 작업을 순차적으로 실행할 뿐입니다.

비동기 처리에서 소스 코드의 평가와 실행을 제외한 모든 처리는 브라우저 또는 Node.js에서 처리합니다. 예를 들어, 타이머 함수인 setTimeout의 콜백 함수의 평가와 실행은 자바스크립트 엔진이 실행하지만, 호출 스케줄링을 위한 타이머 설정과 태스크 큐에 푸시하는 것은 브라우저 또는 Node.js가 담당합니다. 이를 위해 브라우저에서는 이벤트 루프와 태스크 큐를 제공합니다.

  1. 🥦 태스트 큐 : 비동기 함수의 콜백 함수나 이벤트 핸들러가 일시적으로 저장되는 영역입니다.

  2. 🥬 이벤트 루프 : 이벤트 루프는 콜 스택이 현재 실행 중인 실행 컨텍스트가 존재하는지 확인하고, 태스크 큐에 대기 중인 함수가 있는지 반복적으로 확인합니다. 만약 콜 스택이 비어있고 태스크 큐에 대기 중인 함수가 존재한다면 이벤트 루프는 순차적으로 태스크 큐에 존재하는 대기 중인 함수를 콜 스택으로 이동시킵니다. 콜 스택으로 이동된 함수는 곧바로 실행됩니다. 즉, 태스크 큐에 일시적으로 보관되는 함수들은 모두 비동기 처리 방식으로 동작합니다.

자바스크립트 엔진은 싱글 스레드 방식으로 동작합니다. 이때 싱글 스레드로 동작하는 것은 브라우저가 아닌 자바스크립트 엔진입니다. 만약 모든 코드들이 자바스크립트 엔진에서 싱글 스레드 방식으로 동작한다면 비동기 처리는 가능하지 않습니다. 🔑 즉, 자바스크립트 엔진은 싱글 스레드 방식으로, 브라우저는 멀티 스레드 방식으로 동작합니다.

profile
Frontend Dev

0개의 댓글