자바스크립트의 비동기 처리 과정
September 05, 2023
자바스크립트의 비동기 처리 과정
1. 자바스크립트 엔진
자바스크립트는 기본적으로 싱글 스레드에서 동작한다.
싱글 스레드라는 말은 하나의 call stack에서 한번에 하나의 task밖에 처리할 수 없다는 말과 같다.
그래서 비동기를 이용하여 효율적으로 task를 처리한다.
그렇다면 어떻게 동작하여 효율성을 높이는지 궁금증이 생긴다.
자바스크립트 엔진은 코드를 실행하는 일을 하고, 비동기적인 로직들은 모두 Web API에서 처리된다.
이미지 출처: (https://sculove.github.io/post/javascriptflow/)
2. Event Loop, Queue
Event Loop는 자바스크립트 엔진과 브라우저의 Web API 사이에서 작동하여 task 순서를 제어한다.
콜 스택이 비어있을 때 큐에서 task를 꺼내 콜 스택에 넣는 역할을 한다.
자바스크립트는 이 Event Loop와 큐들을 이용하여 비동기 작업을 수행한다.
직접적인 작업은 Web API에서 처리하고 완료 시 콜백을 큐로 받아서 처리하게 되는데,
여기서 큐에 task가 있는지 매번 검사하여 콜 스택으로 넣어주는 역할을 하는 것이 Event Loop이다.
3. 처리 과정
console.log("script start");
setTimeout(function() {
console.log("setTimeout");
}, 0);
Promise.resolve().then(function() {
console.log("promise1");
}).then(function() {
console.log("promise2");
});
requestAnimationFrame(function {
console.log("requestAnimationFrame");
})
console.log("script end");
위와 같은 코드가 있다고 가정을 해보자.
결과는 아래와 같다.
script start
script end
promise1
promise2
requestAnimationFrame
setTimeout
순서
- 첫번째로는 콜 스택에 함수들이 올라갈 것이다.
- 스크립트가 실행되고 console.log(‘script start’) 가 처리된다.
- 그 다음 setTimeout 함수가 콜 스택에 올라가게 되는데 Web API에게 setTimeout을 요청하고 스택에서 빠진다.
- Web API는 작업 완료 후 콜백 함수를 task queue에 등록한다.
- Promise 작업이 콜 스택에 올라오고 Web API에게 Promise 작업을 요청하고 스택에서 빠진다.
- Web API는 작업 완료 후 콜백 함수를 microtask queue에 등록한다.
- requestAnimationFrame 작업이 콜 스택에 올라오고 Web API에게 작업을 요청하고 스택에서 빠진다.
- Web API는 작업 완료 후 콜백 함수를 Animation frames에 등록한다.
- console.log(‘script end’)가 처리된다.
- 스크립트 실행이 완료되고 콜 스택이 비워진다.
- Event Loop가 콜 스택이 비어있음을 감지하고 가장 먼저 microtask queue에 등록된 콜백 함수를 콜 스택에 등록한다.
- 첫번쨰 Promise의 콜백 함수가 실행되어 console.log(‘promise1’) 이 처리된다.
- 콜 스택에서 첫번째 then 콜백 함수가 빠지고 두번째 then 콜백 함수를 microtask queue에 넣는다.
- Event Loop가 콜 스택이 비었음을 감지하고 microtask queue에 있는 두번째 then 콜백 함수를 콜 스택에 등록한다.
- 두번째 콜백 함수의 console.log(‘promise2’)가 처리되고 스택에서 빠진다.
- Event Loop가 콜 스택이 비었음을 감지하고 두번째로 animation frames에 등록된 콜백 함수를 콜 스택에 등록한다.
- 브라우저는 렌더링 작업을 하여 UI를 업데이트하고 스택에서 빠진다.
- Event Loop가 콜 스택이 비었음을 감지하고 마지막으로 task queue에 등록된 콜백 함수를 콜 스택에 등록한다.
- setTimeout 함수가 실행되어 console.log(‘setTimeout’)이 처리되고 스택에서 빠진다.
❗️ 기억해야할 것
- 비동기 작업으로 등록되는 작업은 task, microtask, animation frame 작업으로 구분된다.
- microtask, animationframe 작업 이후에 task 작업이 처리된다.
📂 참고자료