JavaScript 는 싱글 스레드 언어인데 비동기 작업이 가능한가?

2025. 4. 1. 19:31개발자 블로깅/오늘의 TIL

싱글 스레드 언어라는 것은 하나의 작업만 수행할 수 있다는 것인데 그렇다면 비동기 작업을 어떻게 할 수 있다는 것인가? 의문을 시작으로 작성한 글 입니다.

✅ 결론

자바스크립트는 싱글 스레드(Single-threaded) 언어지만, 비동기 작업이 가능한 건 이벤트 루프(Event Loop)와 Web APIs (또는 Node APIs) 덕분입니다.

 

🌱 기본 전제: 자바스크립트는 싱글 스레드

  • 자바스크립트는 한 번에 한 작업만 처리할 수 있음
  • 즉, 콜 스택(Call Stack)에 하나씩 쌓고 처리하는 구조
  • 그런데 이런 구조면, 네트워크 요청이나 타이머 같은 작업을 하면 브라우저가 멈춰야 하지 않을까?


🤔 그럼 어떻게 비동기가 가능할까?

👉 핵심 키워드: 이벤트 루프(Event Loop) + Web APIs
자바스크립트가 직접 비동기를 처리하는 게 아니라, 브라우저Node.js가 대신 처리해주는 구조 입니다.

🧩 작동 원리 요약

예시 코드

console.log('1');

setTimeout(() => {
  console.log('2'); //비동기 작업
}, 1000);

console.log('3');

출력 결과는? 

1
3
2

 

내부 동작 흐름은 ?

  1. console.log('1') → 바로 실행됨
  2. setTimeout(...) →
    • 브라우저의 Web API가 이 타이머를 처리함
    • 콜백 함수는 바로 실행되지 않고, 타이머 완료 후 **태스크 큐(Task Queue)**로 이동
  3. console.log('3') → 바로 실행됨
  4. **이벤트 루프(Event Loop)**가
    • 콜 스택이 비는 순간을 기다렸다가
    • 큐에 있는 console.log('2') 콜백을 콜 스택으로 옮겨서 실행

정리 : setTimeout은 Web API가 타이머를 관리하고, 1초 후 콜백을 태스크 큐에 넣고,
이벤트 루프가 콜 스택이 비었을 때 이 콜백을 실행하기 때문이야.

javascript single-threaded

콜 스택    ← 자바스크립트 엔진이 실제로 코드를 실행
   ↓
Web APIs  ← 타이머, AJAX, DOM 이벤트 같은 작업 위임
   ↓
태스크 큐 ← 완료된 비동기 콜백 대기
   ↓
이벤트 루프 ← 콜 스택이 비면 큐에서 꺼내 실행

- 이벤트 루프는 콜 스택이 비었는지 체크하고, 비었을 때 대기 중인 작업을 실행 해주는 역할을 함

콜 스택, 태스크 큐, Web API, 이벤트 루프의 관계

 

  • 콜 스택: 자바스크립트가 실제로 코드를 실행하는 공간
  • Web API: 브라우저가 제공하는 비동기 작업 처리 공간
  • 태스크 큐: 완료된 비동기 작업이 대기하는 공간
  • 이벤트 루프: 콜 스택이 비면 큐에서 콜백을 꺼내 실행

 

 

📝  정리

  • 자바스크립트는 싱글 스레드이지만,
  • 비동기 작업은 브라우저나 Node.js의 환경에서 처리되고,
  • 이벤트 루프가 콜백을 적절히 실행해주기 때문에 비동기 처리가 가능하다!
  • 싱글 스레드이지만, 이벤트 루프라는 강력한 메커니즘을 통해 마치 멀티스레드처럼 동작 할 수 있음
  • Promise.then , async/await, MutationObserver 등은 마이크로태스크 큐 라는 별도 공간으로 들어가며 태스크보다 우선순위가 높아, 콜 스택이 비면 마이크로태스크를 먼저 모두 처리하고 나서 태스크 큐로 넘어가게 된다.