모던 자바스크립트 Deep Dive 42장-비동기 프로그래밍

HustleKang·2022년 5월 18일

동기 처리와 비동기 처리

함수 코드의 평가를 마치고 생성된 함수의 실행 컨텍스트가 실행 컨텍스트 스택에 푸시된다는 것은
함수 실행의 시작을 의미함
또한 여러개의 함수가 호출된 순서대로 실행되는 것은 호출된 순서대로 해당 함수의 실행 컨텍스트가 만들어지고 실행 컨텍스트 스택에 푸시되기 때문
즉 함수의 실행 순서는 실행 컨텍스트 스택이 관리한다

그런데 자바스크립트 엔진은 실행 컨텍스트 스택이 딱 1개
한 번에 최대 1개의 함수만 실행할 수 있다는 뜻
즉 자바스크립트 엔진은 한 번에 하나의 테스크만 실행할 수 있는 싱글 스레드 방식으로 동작함
처리 시간이 오래 걸리는 테스크가 실행되면 대기 중인 테스크는 중단되는 블로킹이 발생

function sleep(callback,delay){
  const delayUntil = Date.now() + delay;
  while (Date.now() < delayUntil);
  callback();
}
function a(){
  console.log('a');
}
function b(){
  console.log('b');
}

sleep(a,3000); // 3초 뒤에 a가 실행되고 
b(); // b 실행됨

위와 같이 현재 실행 중인 테스크가 종료될 때까지 그 다음 실행할 테스크가 대기하는 방식을 동기 처리

sleep 함수 대신 setTimeout함수로 똑같은 상황을 만들어보면

function a(){
    console.log('a');
}
function b(){
    console.log('b');
}
setTimeout(a,3000);
b();

b 함수가 먼저 실행되고 3초 뒤에 a 함수가 실행 된다

현재 실행 중인 테스크가 종료되지 않은 상태여도 다음 테스크를 곧바로 실행하는 방식을 비동기 처리

타이머 함수와 HTTP 요청, 이벤트 핸들러는 비동기 처리 방식으로 동작함

이벤트 루프와 테스크 큐

자바스크립트는 싱글 스레드이지만 멀티 스레드인것처럼 동작하게 해주는 것이 브라우저에 내장된 이벤트 루프이다

자바스크립트 엔진을 2개의 영역으로 구분하면

  • 콜 스택 = 실행 컨텍스트 스택
  • 힙 : 객체가 저장되는 메모리 공간, 실행 컨텍스트는 힙에 저장된 객체를 참조, 힙은 동적 할당을 위해 구조화 되어있지 않다

자바스크립트 엔진은 소스코드의 평가와 실행을 담당하고
그 외의 비동기 처리를 위한 모든 처리는 브라우저나 Node.js가 담당함

  • 테스크 큐 (task queue, event queue, callback queue)

    : 비동기 함수의 콜백 함수 or 이벤트 핸들러가 일시적으로 보관되는 영역

  • 이벤트 루프 : 콜 스택이 비어있는지, 테스크 큐에 대기 중인 함수가 있는지를 반복해서 확인하여 비어있으면 테스크 큐에 있는 함수를 콜 스택으로 이동시킴
    -> 이동된 함수는 실행됨

// b 함수가 먼저 실행되고 a가 나중에 실행됨
function a(){
	console.log('a');
}
function b(){
	console.log('b');
}

setTimeout(a,0);
b();
  1. 전역 코드가 평가되고 전역 실행 컨텍스트가 콜 스택에 푸시
  2. setTimeout 함수가 실행되어 콜백 함수 스케줄링을 마치고 콜 스택에서 팝
    • 브라우저는 타이머 설정 후 타이머가 만료되면 a함수를 테스크 큐에 푸시,0ms로 지정했지만 4ms이하는 4ms로 설정됨
    • b 함수가 호출되어 실행 컨텍스트를 생성하고 콜 스택에 푸시, b 함수 실행 마친 뒤 콜 스택에서 팝
  3. 더이상 실행할 전역 코드가 없으므로 전역 실행 컨텍스트 콜 스택에서 팝
  4. 이벤트 루프가 콜 스택이 비었음을 감지하고 테스크 큐에서 기다리던 a를 콜 스택으로 이동, a실행 후 팝

setTimeout은 설정한 타이머가 만료되면 콜백 함수를 테스크 큐로 푸시하는 것이고 콜 스택이 비어야 테스크 큐에서 콜 스택으로 이동하기 때문에 설정한 시간에 정확히 호출되지 않고 지연될 수도 있음
setTimeout이 호출되어 실행되는건 자바스크립트 엔진이
타이머 설정과 테스크 큐에 등록하는 처리는 브라우저가 한다

자바스크립트 엔진은 싱글 스레드로 동작하고 브라우저는 멀티 스레드로 동작

이웅모, 『모던 자바스크립트 Deep Dive』, 위키북스(2021)

profile
grindin'

0개의 댓글