뚜벅

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

JavaScript

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

초코맛젤리 2022. 12. 31. 00:15
 

모던 자바스크립트 Deep Dive - 실행 컨텍스트

실행 컨텍스트 실행 컨텍스트를 알면 호이스팅과 클로저, 코드 실행 순서를 이해하는데 도움이 되기 때문에 정리합니다. 소스 코드의 타입 - 전역 코드 전역 변수를 관리하기 위해 최상위 스코

l-lsh.tistory.com

 

자바스크립트 엔진은 싱글 스레드 방식으로 동작하며, 하나의 콜스택을 가집니다. 

그렇기 때문에 태스크들이 여러 개 있더라도 순차적으로 하나씩 태스크를 처리하는데 

이것을 동기 처리라고 합니다. 

 

동기 처리:  현재 실행 중인 태스크가 종료할 때까지 다음에 실행될 태스크가 대기하는 방식

- 장점 : 태스크를 순서대로 하나씩 처리하기 때문에 실행 순서가 보장된다.

- 단점 : 태스크가 하나씩 처리되기 때문에 앞선 태스크가 시간이 오래 걸리는 경우 블로킹이 발생한다.

블로킹 : 작업 중단

// setTimeout 유사 함수, delay 후 콜백 함수 실행(func)
function sleep(func, delay) {
    const delayUntil = Date.now() + delay
    
    while(Date.now() < delayUntil);
    func()
 }
 
 function foo(){
     console.log('foo')
 }
 
 function bar(){
     console.log('bar')
 }
 
 sleep(foo, 3 * 1000)
 
 bar() // 3초동안 블로킹이 발생한다.

 

 

하지만 브라우저가 동작하는 것을 보면 많은 태스크들이 동시에 처리되는것 처럼 느껴집니다. 

이유는 비동기 처리에서 소스코드의 평가와 실행을 제외한 모든 처리는 브라우저 또는 Node.js 에서 실행되기

때문입니다. 

 

예를 들면  아래와 같은 코드가 있을때, 

function foo(){
     console.log('foo')
 }
 
 function bar(){
     console.log('bar')
 }
 
 setTimeout(foo, 3*1000)
 bar() // 블로킹이 발생하지 않는다.

실행 순서

1. 전역 코드가 평가 되어 전역 실행 컨텍스트가 생성되고 콜 스택( 실행 컨텍스트 스택)에 푸시된다.

2. 전역 실행 컨텍스트 실행

3. setTimeout 함수가 호출되고, setTimeout 함수의 함수 실행 컨텍스트가 생성되고 콜 스택에 푸시된다.

4. setTimeout 함수가 실행되고, 콜 스택에서 팝된다.

이때, 브라우저에서 타이머가 만료를 기다리다가 만료되면 태스크 큐에 콜백함수를 푸시한다. (여기서는 foo) (병행 처리 )

5. bar 함수가 호출되어 콜 스택에 푸시되고, 실행 종료 후 콜 스택에서 팝된다.

6. 전역 실행 컨텍스트가 팝된다.

7. 이때 콜 스택에 처리할 태스크가 없기 때문에 이벤트 루프에 의해 태스크 큐에서 대기 중인 foo가 콜 스택에 푸시된다.

8. foo 실행 컨텍스트가 콜스택에 푸시되고, 실행 후 콜스택에서 팝된다. 

 

태스크 큐: 비동기 함수의 콜백 함수 또는 이벤트 핸들러가 일시적으로 보관되는 영역이다.

프로미스의 후속 처리 메서드(then, catch, finally)는 마이크로태스크 큐에 보관되며 우선순위는 마이크로태스크 큐가 더 높다.

이벤트 루프: 콜 스택을 관찰하다가 비어있으면, 태스크 큐에 대기 중인 함수를 체크하고 있다면 콜스택으로 이동시킨다.

 

이처럼 비동기 처리는 브라우저에서 병행 처리 되기 때문에 블로킹이 발생하지 않고 동시에 태스크를 수행하는 것처럼 보입니다.

 

비동기 처리: 현재 실행 중인 태스크가 종료되지 않은 상태라 해도 다음 태스크를 곧바로 실행한다.

- 장점: 블로킹이 발생하지 않는다.

- 단점: 태스크의 실행 순서가 보장되지 않는다. 

 

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