[JS] 자바스크립트 이벤트 루프: 비동기 작업의 이해

최지나·2024년 5월 27일
2

CS

목록 보기
55/55
post-thumbnail

개요

자바스크립트는 싱글 스레드 언어로, 동시에 하나의 작업만 실행할 수 있다. 그러나 실제 웹 애플리케이션에서는 다양한 비동기 작업(예: 네트워크 요청, 타이머 등)을 처리해야 한다.
=> 이 문제를 해결하기 위해 자바스크립트는 이벤트 루프라는 메커니즘을 사용.

호출 스택

  • 호출 스택은 현재 실행 중인 함수와 함수 호출을 추적하는 자료 구조.
  • 함수가 호출되면 스택의 맨 위에 추가되고, 함수 실행이 끝나면 스택에서 제거.

예시 1: 동기 작업

function first() {
  second();
  console.log("첫 번째");
}

function second() {
  third();
  console.log("두 번째");
}

function third() {
  console.log("세 번째");
}

first();
  • 실행 순서: "세 번째" -> "두 번째" -> "첫 번째"
  • 호출 스택
third()
second()
first()
anonymous  # 가상 전역 컨텍스트. 항상 존재

예시 2: 비동기 작업

function run() {
  console.log("3초 후 실행");
}

console.log("시작");
setTimeout(run, 3000);
console.log("끝");
  • 실행 순서: "시작" -> "끝" -> "3초 후 실행"
  • 이를 호출 스택만으로 이해하기는 무리가 있다 -> 이벤트 루프의 개념이 필요.

백그라운드

  • 타이머, 네트워크 요청, I/O 작업 등 비동기 작업을 처리
  • 비동기 작업 완료 시 콜백 함수가 테스크 큐로 이동

테스크 큐

  • 비동기 작업의 콜백 함수를 대기하는 큐
  • 호출 스택이 비어 있을 때 테스크 큐에 있는 콜백 함수가 호출 스택으로 이동되어 실행

이벤트 루프

  • 호출 스택과 테스크 큐를 감시하며, 호출 스택이 비어 있으면 테스크 큐에서 대기 중인 콜백 함수를 호출 스택으로 이동시킴. 이를 통해 비동기 작업을 효과적으로 관리
  • 이 때 테스크 큐에 Promise의 then/catch/finally 또는 process의 nextTick이 쌓이면 다른 테스크보다 우선 순위가 높아 먼저 호출 스택으로 호출됨. 정확히는 콜백함수들이 마이크로테스크큐에 쌓임.

Promise와 이벤트 루프와의 관계

  • 자바스크립트에서 Promise는 비동기 작업을 관리하는 중요한 객체
  • Promise의 then/finally/catch 등의 메서드는 비동기 작업이 완료된 후 실행할 콜백 함수를 등록 가능. 이러한 콜백 함수들은 마이크로 테스크 큐에 쌓인다.
console.log("Start");

let promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("Success");
  }, 1000);
});

promise.then(result => {
  console.log(result); 
});

console.log("End");

  • 실행 순서

1) anonymous 함수(전역 컨텍스트)가 호출 스택에 있음.
2) console.log('Start') 실행, 호출 스택에 추가되었다가 제거됨.
3) setTimeout 함수 호출, 호출 스택에 추가되었다가 제거됨. 백그라운드로 타이머가 설정됨.
4) console.log('End') 실행, 호출 스택에 추가되었다가 제거됨.
5) 타이머가 백그라운드에서 1초 후 만료됨.
6) 타이머 만료 후 resolve('Success') 콜백 함수가 테스크 큐로 이동.
7) 이벤트 루프가 호출 스택이 비어 있음을 확인하고, 테스크 큐에서 resolve('Success') 콜백을 호출 스택으로 이동하여 실행.
8) promise.then에 등록된 콜백이 호출 스택으로 이동하여 실행됨.
9) console.log('Success')가 호출 스택에 추가되었다가 제거됨.

마무리

  • 이번 글을 통해 자바스크립트의 이벤트 루프와 비동기 작업에 대한 개념을 정리해 보았다. Vue나 React와 같은 프레임워크를 사용하여 화면을 만들 때, 비동기 작업의 작동 원리를 완벽히는 이해하지 못한 채 "이렇게 하면 되겠지"라고 생각하며 코드를 작성했던 경험이 있었던 것 같다.🤒

  • 코드가 잘 동작하는 것에 만족하기보다는, 그 동작 원리를 깊이 이해하고 작성하는 습관을 가지는 것이 중요하다는 것을 다시 한 번 깨달았다. :)

profile
의견 나누는 것을 좋아합니다 ლ(・ヮ・ლ)

0개의 댓글