어떤 엔진, 프레임워크들이든 자신만의 흐름(혹은 라이프사이클)이 존재한다.
자바스크립트의 라이프사이클은 어떻게 되는지 궁금해서 조금 더 자세히 알아보았다.
자바스크립트 자체는 싱글스레드 언어
자바스크립트 언어(ECMAScript) 자체는 싱글 스레드로 되어있어 'Call Stack' 구조만을 가진다.
즉, 명령어가 들어오면 순차적으로 쌓아두고 가장 마지막으로 들어온 명령어가 실행되는 구조이다.
정확히는 명령어가 아니라 '실행 컨텍스트' 이다. 실행 컨텍스트는 렉시컬 환경, Variable Environment, this 바인딩, outer reference 와 같은 요소들을 가지고 있는 객체이고, 이 객체가 Call Stack 내부에 쌓이고 실행되는 것이다.
그렇다면 비동기는 어떻게?
자바스크립트 언어 자체에서는 지원하지 않는다.
브라우저 혹은 Node.js 에서 이러한 부분을 지원해준다.
자바스크립트는 Call Stack을 가지고 있다고 하였다. 위 사진에서 'Web APIs', Task Queue(Macrotask Queue), MicroTask Queue와 Event Loop는 브라우저 혹은 Node.js에서 제공한다고 보면 되겠다.
비동기 실행 순서
console.log(); 는 동기 로직이기 때문에 Call Stack으로 등록된 후 바로 실행된다.

setTimeout() 은 Web API 중 하나이기 때문에 비동기 로직이며, Call Stack에 등록된 후 Web APIs(백그라운드)에 등록된 후 타이머가 실행된다.

백그라운드에 실행되고 있는 로직은 Macrotask Queue에 등록된 후 Promise.resolve()와 then();이 순차적으로 Call Stack에 등록된후 then 내부의 res => console.log(res) 가 Microtask Queue에 등록된다.

Queue보다 console.log('End!);의 로직이 먼저 Call Stack에 등록된 후 실행된다.

이후 Microtask Queue가 먼저 실행된 후

마지막으로 () => {} 콜백와 console.log('Timeout!')이 Call Stack에 올라가며 순차적으로 실행되며 종료된다.
Task는 왜 두 개로 나눠져있는거지?
Web APIs(백그라운드) 에서 일정 시간동안 대기 후 Task 에 등록이 된다.
Promise 와 같은 객체는 ECMAScript 2015(ES6)**부터 도입된 자바스크립트 언어 자체의 비동기 패턴/객체이다.
기존에는 콜백 함수를 중첩해서 비동기를 다루던 방식을 “체이닝 및 에러 처리를 깔끔하게” 만들 수 있도록 한 것이 Promise이다.
결론적으로 Promise는 자바스크립트의 자체 문법, setTimeout같은 것들은 브라우저 및 Node.js에서 제공하는 API인 것이므로 Task가 나눠져있다.
Promise객체는 내부적으로 [[PromiseState]], [[PromiseResult]] 와 같은 내부 슬롯이 등록되어있어 Promise를 관리해준다.
'프로그래밍 > 자바스크립트' 카테고리의 다른 글
렉시컬 환경(Lexical Environment), 클로저 (0) | 2025.01.07 |
---|---|
함수 (function) (0) | 2025.01.06 |
변수 선언과 변수 타입 (0) | 2025.01.06 |