Published on

javascript의 eventloop

eventloop란?

  • javascript가 수행되는 환경의 특징에 대해 고민해볼 필요가 있다. javascript는 비동기로 동작 가능하며, 이로인해 동시에 많은 작업을 수행 가능하다. 하지만 javascript는 단일 스레드 기반의 언어이다. javascript는 기본적으로 한 번에 한 가지 일만 할 수 있다. 이는 즉, javascript를 실행하는 환경인 브라우저 혹은 node.js에서 동시성을 지원해주기 때문에 가능하다. 바로 javascipt에서 동시성을 지원하기 위한 기능이 eventloop 이다.

browser에서 javascript가 실행되는 원리

eventloop structure

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의 상태를 체크하며 각 상태에 맞는 작업을 수행.

동작 순서

    1. js 엔진의 call stack에서 실행되는 함수가 비동기 작업일 경우 web APIs로 이관.
    1. js 엔진이 동기 작업만 수행하는 동안 병렬 작업으로 브라우저 백그라운드에서 web APIs가 비동기 작업을 수행.
    1. web APIs에서 완료된 비동기 작업이 callback queue의 각 역할에 맞는 microtask queue와 macrotask queue에 쌓임.
    1. eventloop가 call stack과 callback queue의 상태를 체크하며 call stack이 비었을 경우 callback queue에 있는 비동기 작업 결과를 이관.
    • 이때, microtask queue의 작업이 우선 이관됨.
    1. 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