- Published on
javascript의 eventloop
eventloop란?
- javascript가 수행되는 환경의 특징에 대해 고민해볼 필요가 있다. javascript는 비동기로 동작 가능하며, 이로인해 동시에 많은 작업을 수행 가능하다. 하지만 javascript는 단일 스레드 기반의 언어이다. javascript는 기본적으로 한 번에 한 가지 일만 할 수 있다. 이는 즉, javascript를 실행하는 환경인 브라우저 혹은 node.js에서 동시성을 지원해주기 때문에 가능하다. 바로 javascipt에서 동시성을 지원하기 위한 기능이 eventloop 이다.
browser에서 javascript가 실행되는 원리
browser 구조
- js 엔진
- memory heap: 메모리 할당을 담당.
- call stack: 코드가 실행될 실행 컨텍스트가 stack 방식(LIFO) 쌓이는 곳.
- web APIs: DOM, AJAX, Timeout등 비동기 작업을 처리 담당.
- callback queue: web APIs에서 처리된 비동기 작업을 queue 방식(FIFO)으로 보관. microtask가 macrotask보다 우선순위가 높음.
- microtask queue: process.nextTick, promises, queueMicrotask, mutationObserver 등
- macrotask queue: requestAnimationFrame, I/O, UI rendering, timer.
- eventloop: call stack과 callback queue의 상태를 체크하며 각 상태에 맞는 작업을 수행.
동작 순서
- js 엔진의 call stack에서 실행되는 함수가 비동기 작업일 경우 web APIs로 이관.
- js 엔진이 동기 작업만 수행하는 동안 병렬 작업으로 브라우저 백그라운드에서 web APIs가 비동기 작업을 수행.
- web APIs에서 완료된 비동기 작업이 callback queue의 각 역할에 맞는 microtask queue와 macrotask queue에 쌓임.
- eventloop가 call stack과 callback queue의 상태를 체크하며 call stack이 비었을 경우 callback queue에 있는 비동기 작업 결과를 이관.
- 이때, microtask queue의 작업이 우선 이관됨.
- js 엔진의 call stack이 비동기 작업의 결과를 수행.
example
console.log('start');
setTimeout(function () {
console.log('setTimeout');
}, 0);
Promise.resolve()
.then(function () {
console.log('promise1');
})
.then(function () {
console.log('promise2');
});
const deley = () => {
for (let i = 0; i < 100000; i++) {
for (let j = 0; j < 100000; j++) {}
}
};
deley();
console.log('end');
// result
start
end
promise1
promise2
setTimeout
ref
- docs
- article
- blog