본문 바로가기
2주차

자바스크립트 동기와 비동기

by 한수정1 2025. 4. 25.

안녕하세요. 웹파트 오비 한수정입니다. 자스정인만큼 자스로 공유과제를 써야겠단 생각에,, 작동원리인 동기와 비동기에 대해 알아보려고 합니다. 시작 !

 

프로그래밍 언어들은 동기(Synchronous) 비동기(Asynchronous)라는 두 가지 서로 다른 실행 방식을 가집니다.

이 차이를 이해하는 가장 쉬운 방법은, 아래와 같이 각 언어에서 1초 쉬기 코드를 비교해보는 것입니다.

 

자바스크립트 예

console.log('W');

setTimeout(() => {
  console.log('E');
}, 1000);

console.log('B');

 

 

자바스크립트의 setTimeout은 비동기 함수입니다.

따라서 'E'를 출력하는 코드는 1초 뒤에 실행되고, 그 사이에 'B'가 먼저 출력됩니다.

 

 

파이썬 예

import time

print("W")
time.sleep(1)  # 1초 동안 멈춤
print("E")
print("B")

 

파이썬의 time.sleep(1)은 동기 함수입니다.

실행이 1초 동안 멈추고, 'E'와 'B'가 그 이후에 순차적으로 출력됩니다.

 

자바 예

public class Main {
    public static void main(String[] args) {
        System.out.println("W");

        try {
            Thread.sleep(1000); // 1초 대기
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("E");
        System.out.println("B");
    }
}

 

자바의 Thread.sleep(1000) 역시 동기 함수입니다.

실행이 1초간 멈춘 뒤, 'E', 'B'가 차례로 출력됩니다.

 

- 자바스크립트: setTimeout과 같은 비동기 함수는 "잠깐 기다리는 동안" 다음 코드를 먼저 실행합니다.

- 파이썬, 자바: sleep 함수는 "정말로 1초 동안 멈춘 뒤" 다음 코드를 실행합니다.

 

이처럼, 자바스크립트는 비동기 처리가 자연스럽게 녹아있는 언어이고, 파이썬과 자바는 명시적으로 동기/비동기를 구분해서 코드를 작성해야 합니다.

 

 

자바스크립트는 왜 비동기 처리가 자연스러울까요?

자바스크립트 비동기의 작동 원리에 대해 알아보겠습니다.

 

 

자바스크립트 비동기의 작동 원리

자바스크립트 싱글 스레드 언어입니다. 즉, 한 번에 하나의 작업만 실행할 수 있습니다.

그런데도 setTimeout, fetch, click 이벤트 같은 비동기 작업이 가능한 이유는 자바스크립트의 이벤트 루프(Event Loop) 덕분입니다.

 

아래 이미지는 자바스크립트 엔진과 브라우저가 협력하여 비동기를 처리하는 구조입니다.

 

자바스크립트의 실행 흐름은 크게 아래처럼 구성되어 있습니다:

  • Heap: 데이터를 저장하는 메모리 공간입니다. 객체나 함수가 생성되면 이곳에 보관됩니다.
  • Call Stack: 실행 중인 함수들이 쌓이는 공간입니다. 위에서 아래로 실행되며, 동기 코드는 이 스택에서 바로 실행됩니다.
  • Web APIs: setTimeout, fetch, DOM 이벤트 같은 비동기 작업을 브라우저가 담당하는 영역입니다. 자바스크립트 엔진이 아닌 브라우저가 이 기능을 처리합니다.
  • Callback Queue: Web API 작업이 끝나고, 실행을 기다리는 콜백 함수들이 대기하는 공간입니다.
  • Microtask Queue: Promise.then 등의 빠른 작업들이 대기하는 공간으로, 콜백 큐보다 우선 실행됩니다.
  • Event Loop: 콜 스택이 비면, 큐에서 대기 중인 작업을 꺼내 실행시킵니다. 이 덕분에 자바스크립트는 비동기 처리를 할 수 있습니다.

 

아래 코드 예시로 보겠습니다. 먼저, 기본 동기 함수입니다. 

const sWeb = () => {
  console.log("javaScript");
};

console.log("Start");
sWeb();
console.log("End");

 

➡ sWeb()이 콜 스택에 쌓이고, console.log가 실행되면서 메시지가 출력됩니다.

 

개발자도구에서 스니펫을 활용해보았습니다. 이미지가 작지만 아래 콘솔과 우측에 호출스택을 순서대로 보시면 됩니다. 

 

 

다음은 비동기 setTimeout 예제입니다.

console.log("Start");

setTimeout(() => {
  console.log("javaScript");
}, 3000);

console.log("End");
  • console.log("Start") → 콜 스택에 쌓이고 즉시 실행됩니다.
  • setTimeout은 브라우저(Web API)가 실행하고, 콜백을 Task Queue에 대기시킵니다.
  • console.log("End") → 바로 실행됩니다.
  • 3초 뒤, 콜백 함수가 콜 스택이 비면 Task Queue에서 올라가서 실행됩니다. → "javaScript"

➡ 이게 바로 이벤트 루프의 역할: 콜 스택이 비면 → Task Queue에서 대기 중인 콜백을 실행시킵니다.

1. 콜 스택      : [console.log("Start")] → 실행
2. Web API      : [setTimeout()] → 3초 타이머 작동
3. 콜 스택      : [console.log("End")] → 실행
4. Task Queue   : [() => console.log("javaScript")] → 대기 중
5. 콜 스택 비면 : Task Queue → 콜 스택으로 이동

 

 

요약하자면,

  • 자바스크립트는 싱글 스레드지만, 이벤트 루프와 태스크 큐를 통해 비동기 처리를 합니다.
  • setTimeout, fetch, 이벤트 리스너 등은 Web API가 처리한 후 콜백을 큐에 등록합니다.
  • 콜 스택이 비면 이벤트 루프가 큐에서 콜백을 가져와 실행합니다.

비동기는 자바스크립트를 이해하는 데 정말 중요한 개념이라 단순히 외우기보다 실행 흐름을 직접 콘솔에 찍어보거나 실행해보면서 공부하는 걸 추천드립니다!

🌟 개념을 탄탄히 잡고, 재미있게 공부하시길 바랍니다! 화이팅입니당🌟