싱글스레드 기반인 자바스크립트가 어떻게 비동기 처리를 하는걸까?

보통의 프로그래밍 언어들은 동기처리 방식을 통해서 코드가 실행된다. 즉, 먼저 작성한 코드부터 순서대로 실행이 되는 구조를 가지고 있다 이를 동기라고 한다. 하지만 자바스크립트의 경우는 비동기 처리 방식을 사용하는데 일을 하다가도 먼저 작성한 코드보다 늦게 작성한 코드가 먼저 실행이 되는 경우가 발생한다.

    function first() {
        setTimeout(() => {
            console.log("first")
        },1000)
    }

    function second() {
        setTimeout(() => {
            console.log("second")
        },500)
    }

    first() 
    second()

아주 대표적인 예제이다 first() 함수를 호출하고 second() 함수를 호출하게 되는데 동기적인 실행이라면 1초가 지나고 first가 콘솔에 나타나고 1.5초가 지난 후 second가 콘솔창에 나타나야하는데 해당 코드를 실행하게 되면 0.5초 후 second가 실행되고 1초 후 first가 실행된다 싱글스레드 기반의 언어인 자바스크립트에서 어떻게 이런 결과가 나오는 것일까?

싱글스레드는 한번에 하나의 작업밖에 수행을 하지못하는 구조인데 싱글스레드를 기반으로 한 자바스크립트는 동시에 작업을 진행한다 이를 알기 위해서는 자바스크립트의 동작원리를 알아야 한다.

자바스크립트 구조

자바스크립트 구조

자바스크립트는 단일 호출 스택과 메모리힙을 가지고 있다 하나의 호출 스택을 가지고 있다 그렇기 때문에 한번에 하나의 함수를 처리하도록 동작이 되는데 아래 그림을 보면 좀더 이해가 쉽다.

출처 원문에서 가져온 예제와 사진이다.

function multiply(x, y) {
    return x * y;
}
function printSquare(x) {
    var s = multiply(x, x);
    console.log(s);
}
printSquare(5);

자바스크립트 구조

Run-to-compleiton 호출 스택에 있는 함수가 실행되고 있을때 해당 함수가 종료되는 시점까지 다른 작업이 중간에 실행되지 못하는 것을 말하는데 이 예제와 자바스크립트 구조만을 본다면 비동기 구조로 동작이 어떻게 되는건지에 대해 더욱 더 의구심이 생길 수 있는 부분이다. 하지만 자바스크립트는 해당 구조로만 작동하는 것이 아니다. 자바스크립트 실행을 관여하는 부분들이 존재하는데 Web API와 TaskQueue, Event Loop와 같은 요소가 존재한다

Web API

Web API는 말 그대로 웹에서 제공하는 API를 말한다 Web API에서는 Timeout이나 DOM 또는 AJAX와 같은 비동기 작업을 진행한다고 한다. 호출 스택에 setTimeout함수가 올라오고 콜백함수와 함께 이를 Web API에 전달하고 호출 스택에 존재하던 setTimeout함수가 제거된다. Web API 에서는 호출 스택에서 보내 준 setTimeout 함수를 동작시키고 콜백함수를 Task Queue에 보내준다.

Task Queue

자바스크립트의 런타임 구성에 속한 Task Queue는 Web API에서 처리한 후 보내준 CallBack 함수를 큐 형태로 저장한다.

Event Loop

Task Quueu에 저장된 CallBack 함수들은 호출 스택에서 실행 중인 작업이 없는지 체크를 해주고 실행 중인 작업이 없다면 이를 호출 스택으로 보내어 주는 역할을 반복해서 한다

자바스크립트 동작원리 출처

자바스크립트는 위와 같은 구조를 갖기 때문에 싱글스레드를 가지고도 비동기 처리가 가능해지는데 이는 단순히 싱글스레드 외에 Web API와 TaskQueu , Event Loop와 같은 요소들이 존재하기 때문에 비동기 처리가 가능하다 즉, 자바스크립트는 함수를 실행하는 역할을 중점으로 하고 코드의 실행은 자바스크립트의 런타임을 담당하는 요소들을 통해서 비동기 처리를 하는 것이다

Notices

자바스크립트 공부를 좀더 해야할 것 같다.