WIL(Weekly I Learned)

[JS] 비동기 함수 동작 방식

borobong230 2023. 10. 26. 12:57

JavaScript는 싱글 스레드 기반의 언어로, 한 번에 하나의 작업만 처리 가능합니다.

그렇다면 setTimeout이나 setInterval 같은 비동기 함수들은 어떻게 처리를 할까요?

 

자바스크립트가 동작하는 방식을 알기 위해서는 아래의 구조를 알 필요가 있습니다.

 

크게 4군데로 나누어져 있는데

  1. Call Stack
    자바스크립트에서 실행 예정인 함수들이 이 곳(Call Stack)에 쌓입니다.
    함수의 실행이 끝난다면 이 곳에서 제거됩니다.

  2. WebAPIs
    브라우저에서 제공하는 API들로, 비동기 작업을 처리합니다.

  3. Callback Queue (콜백 대기열)
    Web APIs에서 완료된 비동기 작업들이, 이 곳(Callback Queue)에서 대기합니다.

  4. Event Loop (이벤트 루프)
    Call Stack이 비었는지 확인 후에 비었다면, Callback Queue에서 대기하고 있는 함수가 있는지 확인 후 Call Stack으로 옮겨 실행합니다.

 

예시 코드

console.log("1");
setTimeout(() => console.log("2"), 0);
console.log("3");

// 결과
// 1
// 3
// 2

 

0초 후에 실행되는 코드니까 
1
2
3
이 출력되어야 하는거 아닌가? 라고 생각할 수 있습니다.

 

하지만 결과는 1,3,2 순서인데요!

 

왜 그런지 자바스크립트가 동작하는 방식을 조금 더 자세하게 봅시다!

 

위의 코드를 간단하게 분석해보자면,

1. [CallStack] console.log("1"), setTimeout, console.log("3")이 쌓입니다.

 

2. [CallStack] console.log("1") 실행 -> 1 출력 -> Call Stack에서 제거됩니다.

 

3. [WebAPIs] 비동기 작업 처리 후 -> Callback Queue (대기열) 로 전달합니다. 

 

4. [CallStack] console.log("3") 실행 -> 3 출력 -> Call Stack에서 제거합니다.

 

5. [Event Loop] Call Stack이 비어 있고, Callback Queue에 대기하고 있는 함수(console.log("2")) 존재해서 Callback Queue에서 Call Stack으로 옮깁니다 

 

6. [CallStack] console.log("2") 실행 -> 2 출력 -> Call Stack에서 제거됩니다.

 

 

위의 순서로 자바스크립트가 동작하기 때문에, 다음과 같은 결과물이 나옵니다.