- Published on
비동기 프로그래밍
비동기 프로그래밍
동기 처리와 비동기 처리
- 함수를 호출하면 함수 코드가 평가되어 함수 실행 컨텍스트가
생성
됨 - 생성된
함수 실행 컨텍스트
는 실행 컨텍스트 스택(= 콜 스택
)에푸시
되고 함수 코드가 실행됨 - 함수 코드의 실행이
종료
되면함수 실행 컨텍스트
는 실행 컨텍스트 스택에팝되어 제거
됨
싱글 스레드
- 자바스크립트 엔진은
단 하나
의 실행 컨텍스트 스택을 가짐(⭐⭐) - 동시에 2개 이상의 함수를 동시에 실행할 수 없으므로 실행 중인
실행 컨텍스트를 제외한 모든 실행 컨텍스트
는 실행대기 중인 태스크
들임 - 싱글 스레드 방식으로 동작하므로 처리에 시간이 걸리는 태스크를 실행하는 경우에는
블로킹
이 발생함
- 현재 실행 중인 태스크가 종료할 때까지 다음에 실행될 태스크가 대기하는 방식을
동기 처리
라고 함- 순서대로 하나씩 처리하므로
실행 순서가 보장
된다는 장점이 있지만, 앞선 태스크가 종료할 때까지 이후 태스크들이블로킹
됨
- 순서대로 하나씩 처리하므로
setTimeout을 이용한 비동기 처리
function foo() {
console.log('foo');
}
function bar() {
console.log('bar');
}
// 타이머 함수 setTimeout은 일정 시간이 경과한 이후에 콜백 함수 foo를 호출
// 타이머 함수 setTimeout은 bar 함수를 블로킹 하지 않음
setTimeout(foo, 3 * 1000);
bar();
// bar 호출 -> (3초 경과 후) foo 호출
setTimeout
함수는 태스크를 블로킹하지 않고 곧바로 실행함- 현재 실행 중인 태스크가 종료되지 않은 상태라 해도 다음 태스크를 곧바로 실행하는 방식을
비동기 처리
라고 함
- 현재 실행 중인 태스크가 종료되지 않은 상태라 해도 다음 태스크를 곧바로 실행하는 방식을
타이머 함수인
setTimeout
과setInterval
, HTTP 요청, 이벤트 핸들러는 비동기 처리 방식으로 동작함
이벤트 루프와 태스크 큐
- 자바스크립트 엔진이 싱글 스레드로 동작하지만 브라우저 동작하는 것을 보면 많은 태스크가 동시에 처리되는 것처럼 느껴지는데, 이런
동시성
을 지원하는 것이이벤트 루프
- 이벤트 루프와 브라우저 환경은 위의 그림처럼 표현할 수 있음
- 구글의 V8 자바스크립트 엔진을 비롯한 대부분의
자바스크립트 엔진
은 크게 2개 영역으로 구분할 수 있음
자바스크립트 엔진 영역
태스크가 요청되면
콜 스택
을 통해 요청된 작업을 순차적으로 실행함
콜 스택
(Call Stack)- 소스코드 평가 과정에서 생성된
실행 컨텍스트
가추가
되고제거
되는 스택 자료구조를콜 스택
이라 함
- 소스코드 평가 과정에서 생성된
힙
(Heap)- 객체가 저장되는
메모리 공간
으로서 콜 스택의 요소인 실행 컨텍스트는 힙에저장된 객체를 참조
함- 객체는 원시 값과 달리
크기가 정해져 있지 않음
- 객체는 원시 값과 달리
- 메모리 공간의 크기를
런타임에 결정
(동적 할당)해야 함- 객체가 저장되는 메모리 공간인 힙은 구조화되어 있지 않음
- 객체가 저장되는
브라우저 환경
소스코드의 평가와 실행을 제외한
모든 처리
는 자바스크립트 엔진을 구동하는 환경인브라우저
또는Node.js
가 담당
태스크 큐
(task queue/event queue/callback queue)setTimeout
이나setInterval
과 같은 비동기 함수의 콜백 함수 또는 이벤트 핸들러가 일시적으로 보관되는 영역
이벤트 루프
(event loop)- 콜 스택에 현재 실행 중인 실행 컨텍스트가 있는지, 태스크 큐에 대기 중인 함수(콜백 함수, 이벤트 핸들러 등)가 있는지 반복해서 확인
- 콜 스택이 비어 있어 있거나 태스크 큐에 대기중인 함수가 있다면
이벤트 루프
는 순차적으로 태스크 큐에 대기 중인 함수를콜 스택으로 이동
시킴
- 콜 스택이 비어 있어 있거나 태스크 큐에 대기중인 함수가 있다면
- 콜 스택에 현재 실행 중인 실행 컨텍스트가 있는지, 태스크 큐에 대기 중인 함수(콜백 함수, 이벤트 핸들러 등)가 있는지 반복해서 확인
실행 순서
function foo() {
console.log('foo');
}
function bar() {
console.log('bar');
}
setTimeout(foo, 0); // 0초(실제는 4ms) 후에 foo 함수가 호출됨
bar();
- 전역 코드가
평가
되어 전역 실행 컨텍스트가 생성되고콜 스택에 푸시됨
- 전역 코드가
실행
되어setTimeout
함수 호출setTimeout
함수의 함수 실행 컨텍스트가 생성되고 콜 스택에 푸시되어현재 실행 중인 실행 컨텍스트가 됨
setTimeout
함수가 실행되면 콜백 함수를 호출 스케줄링하고 종료되어 콜 스택에서 팝됨- 타이머 설정과 타이머가 만료되면 콜백 함수를
태스크 큐에 푸시
하는 것은브라우저의 역할
- 타이머 설정과 타이머가 만료되면 콜백 함수를
브라우저
가 수행하는 4-1과자바스크립트 엔진
이 수행하는 4-2는병행처리
됨브라우저
- 타이머를 설정하고 타이머의 만료를 기다리고 만료된 후 콜백 함수 foo가 태스크 큐에 푸시됨
- 4ms 후에 콜백 함수 foo가 태스크 큐에 푸시되어 대기하게 됨
자바스크립트 엔진
bar 함수가 호출
되어 bar 함수의 함수 실행 컨텍스트가 생성되고 콜 스택에 푸시되어 현재실행 중인 실행 컨텍스트
가 됨bar 함수가 종료
되어 콜 스택에서 팝되는데, 이때 브라우저가 설정한 타이머가 4ms 경과했다면foo 함수는 태스크 큐에서 대기중
인 상태
- 전역 코드 실행 종료 후
전역 실행 컨텍스트
가 콜 스택에서 팝됨 이벤트 루프
에 의해 콜 스택이비어 있음이 감지
되고 태스크 큐에서 대기 중인 콜백 함수 foo의 함수 실행 컨텍스트가 생성되고 콜 스택에 푸시되어 현재 실행 중인 실행 컨텍스트가 됨자바스크립트 엔진
은싱글 스레드
로 동작브라우저
는멀티 스레드
로 동작
Referenced
- 이응모, 『모던 자바스크립트 Deep Dive』, 위키북스(2022.4.25), 809 ~ 815p