Notice
Recent Posts
Recent Comments
Link
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Archives
Today
Total
관리 메뉴

JAN's History

📚 자바스크립트의 비동기 프로그래밍 본문

Javascript

📚 자바스크립트의 비동기 프로그래밍

JANNNNNN 2024. 11. 5. 15:34

자바스크립트에서 동기와 비동기 프로그래밍을 이해하는 것은 매우 중요한데요! 특히 자바스크립트는 단일 스레드로 동작하기 때문에, 비동기 처리를 통해 효율적으로 작업을 처리하는 것이 핵심입니다. 이제 차근차근 비동기 프로그래밍을 알아볼까요?

📌 동기 프로그래밍이란?

동기 프로그래밍(Synchronous Programming)각 작업이 순차적으로 실행되는 방식이에요. 즉, 한 작업이 끝나기 전까지는 다른 작업을 수행하지 않고 기다리는 것이죠.예시 이미지에서도 동기 프로그래밍은 주문 순서대로 순차적으로 음료가 나오는 것을 알 수 있죠?

동기 프로그래밍 예시

function longWork() {
  const now = new Date();
  const millseconds = now.getTime(); // 현재 시간을 밀리초로 가져옴
  const afterTwoSeconds = millseconds + 2 * 1000; // 2초 더한 시간 설정

  while (new Date().getTime() < afterTwoSeconds) {
    // 2초가 지나기 전까지 반복문을 실행 (즉, 시간이 멈춘 것처럼 동작함)
  }
  console.log('완료'); // 시간이 다 지나면 '완료'를 출력
}

console.log('Hello');
longWork(); // 2초가 걸리는 작업을 수행
console.log('World'); // longWork가 끝나고 나서야 실행됨

이 예시에서는 longWork() 함수가 동기적으로 실행되기 때문에, longWork()가 끝나기 전까지는 다음 줄 코드인 console.log('World')가 실행되지 않아요. 그래서 실행 결과는 아래와 같아요:

Hello
완료
World

동기 프로그래밍은 간단하지만, 작업이 오래 걸리면 그만큼 다른 작업도 지연되는 문제가 있어요. 이럴 때 비동기 프로그래밍이 필요해요!

📌 비동기 프로그래밍이란?

비동기 프로그래밍(Asynchronous Programming)작업을 비동기적으로 처리하여, 하나의 작업이 완료될 때까지 다른 작업을 멈추지 않고 계속 실행할 수 있어요. 자바스크립트에서는 콜백 함수, 프로미스(Promise), async/await 등의 방법으로 비동기 처리를 할 수 있어요.

비동기 프로그래밍 예시

function longWork2() {
  setTimeout(() => {
    console.log('완료'); // 2초 후에 '완료'가 출력됨
  }, 2000); // 2초를 기다린 후에 작업 수행
}

console.log('Hello');
longWork2(); // 비동기 작업 실행, 하지만 기다리지 않고 다음 코드를 실행함
console.log('World'); // longWork2가 끝나기 전에 실행됨

여기서는 longWork2() 함수가 비동기적으로 실행되기 때문에, longWork2()가 끝나기 전에 다음 줄 코드인 console.log('World')가 실행돼요. 실행 결과는 다음과 같아요.

Hello
World
완료

즉, 2초 동안 longWork2()가 기다리는 동안에도 다른 코드가 먼저 실행되는 거죠. 이렇게 자바스크립트는 비동기적으로 코드를 처리함으로써, 긴 시간이 걸리는 작업이 프로그램 전체를 멈추지 않도록 해요.


💡 비동기 처리를 위한 핵심 개념

https://medium.com/sessionstack-blog/how-does-javascript-actually-work-part-1-b0bacc073cf

자바스크립트 엔진은 메모리 힙과 콜 스택으로 구성되어 있는데요. 자바스크립트는 단일 스레드라고 했죠? 이 의미는 콜 스택이 하나라는 뜻이랍니다. 즉, 멀티가 되지 않아 하나씩 처리가 된다는 의미입니다.

그래서, 우리는 엔진을 2가지를 가지고 있지만 실제로는 훨씬 더 많은 것이 있습니다. 우리는 브라우저에서 제공하는 웹 API라고 불리는 것들을 가지고 있는데 이게 대표적으로 DOM, AJAX, setTimeout 등이 있습니다. 또 이벤트 루프와 콜백 큐가 있습니다. 

이 사진에 대해서 자세하게 살펴봅시다!

출처: https://charming-kyu.tistory.com/19

1. 메모리 힙(Memory Heap)

  • 자바스크립트는 메모리 힙을 사용해 객체나 배열,함수 등의 참조타입이 동적으로 할당되는 메모리를 관리해요
  • 모든 함수와 변수가 메모리 힙에저장되며 가비지 컬렉션을 통해 더이상 사용되지 않는 메모리를 자동으로 해제해요.

2. 콜 스택(Call Stack)

  • 자바스크립트는 함수를 호출할 때마다 해당 함수를 콜 스택(Call Stack)에 쌓아요.
  • 원시 타입 데이터 (ex)  변수 a = 10)은 콜 스택 메모리에 값이 저장돼요.
  • 콜 스택은 LIFO(Last In, First Out) 방식으로 작동해서, 가장 최근에 호출된 함수가 먼저 실행된답니다.
  • 그리고 함수 실행이 끝나면 스택에서 제거됩니다.

3. 이벤트 루프(Event Loop)

  • 자바스크립트는 비동기 작업을 처리할 때 이벤트 루프(Event Loop)를 통해 관리해요.
  • 콜백 함수나 비동기 작업은 콜 스택이 비어있을 때 태스크 큐(Task Queue)에서 콜 스택으로 이동하여 실행돼요.
  • 이벤트 루프는 콜 스택이 비어 있는지 확인하고, 비어 있으면 태스크 큐에 있는 작업을 콜 스택에 추가하는 역할을 해요.

4. 콜백 큐(Callback Queue)

  • 비동기 작업이 완료된 후 실행될 콜백 함수들이 대기하는 곳이예요.
  • 예를 들어 콜백 큐에 있는 onClick(), onLoad(), onDone()에 대해 알아볼게요.
  • onClick(): 이는 사용자가 웹 페이지의 요소(예: 버튼)를 클릭했을 때 실행되는 이벤트 핸들러에요. 예를 들면,
document.getElementById("myButton").onClick = function() {
  console.log("버튼이 클릭되었습니다!");
};
  • onLoad(): 이는 웹 페이지나 특정 리소스(이미지, 스크립트 등)의 로딩이 완료되었을 때 실행되는 이벤트 핸들러입니다. 예를 들면:
window.onload = function() {
  console.log("페이지 로딩이 완료되었습니다!");
};

이러한 이벤트 핸들러와 콜백 함수들은 비동기적으로 실행되며, 해당 이벤트가 발생하거나 작업이 완료되면 Callback Queue에 추가됩니다. 그 후 Event Loop에 의해 Call Stack이 비어있을 때 실행됩니다.

5. 웹 API(Web APIs)

  • 브라우저에서 제공하는 기능들입니다.
  • 자바스크립트 엔진 자체에는 없지만, 브라우저 환경에서 사용할 수 있습니다.
  • 예를 들어 DOM(Document Object Model): 웹 페이지의 구조를 표현하고 조작할 수 있게 해주는 인터페이스 입니다.
  • 이 코드는 DOM을 사용해 버튼에 클릭 이벤트를 추가합니다.
document.getElementById("myButton").addEventListener("click", function() {
  alert("버튼이 클릭되었습니다!");
});
  • AJAX (XMLHttpRequest): 서버와 비동기적으로 데이터를 주고받을 수 있게 해주는 기술입니다.
  • 이 코드는 서버에서 데이터를 가져옵니다.
let xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/data", true);
xhr.onload = function() {
  if (xhr.status === 200) {
    console.log(xhr.responseText);
  }
};
xhr.send();

핵심 정리:

  • 자바스크립트 엔진이 비동기 작업(예: setTimeout)을 만나면 Web API에 작업을 위임합니다.
  • 비동기 작업이 Web API에서 처리되는 동안, 자바스크립트 엔진은 다음 코드를 계속 실행합니다.
  • Web API에서 작업이 완료되면, 해당 콜백 함수를 Callback Queue에 추가합니다.
  • Event Loop는 지속적으로 Call Stack이 비어있는지 확인합니다.
  • Call Stack이 비면, Event Loop는 Queue에서 콜백을 가져와 Call Stack에 추가하여 실행합니다.

헷갈릴만한 부분: 콜 스택과 콜백 큐의 차이점

  • 콜 스택(Call Stack)과 콜백 큐(Callback Queue)는 자바스크립트의 비동기 프로그래밍과 관련된 중요한 개념이에요. 이 두 개념은 서로 다른 역할을 수행하지만, 함께 작동하여 자바스크립트가 비동기 작업을 효율적으로 처리하도록 도와줘요.

1. 콜 스택 (Call Stack)

정의

콜 스택은 현재 실행 중인 함수의 목록을 관리하는 데이터 구조로, LIFO(Last In, First Out) 방식으로 작동해요. 즉, 가장 최근에 호출된 함수가 가장 먼저 실행되고, 호출이 끝나면 스택에서 제거돼요.

작동 방식

  • 자바스크립트 엔진은 코드를 실행할 때 모든 함수 호출을 콜 스택에 쌓아 두고, 가장 상위에 있는 함수부터 실행해요.
  • 함수가 실행되면 해당 함수의 실행 컨텍스트가 스택에 추가되고, 함수가 종료되면 해당 실행 컨텍스트가 스택에서 제거돼요.

2. 콜백 큐 (Callback Queue)

정의

콜백 큐는 비동기 작업의 콜백 함수를 대기시키는 데이터 구조로, FIFO(First In, First Out) 방식으로 작동해요. 즉, 가장 먼저 대기한 콜백 함수가 먼저 실행돼요.

작동 방식

  • 비동기 작업(예: setTimeout, AJAX 요청 등)이 완료되면 해당 작업의 콜백 함수는 콜백 큐에 추가돼요.
  • 이벤트 루프는 콜 스택이 비어 있는지 확인한 후, 비어 있다면 콜백 큐에서 대기 중인 콜백 함수를 콜 스택으로 이동시켜 실행해요.

3. 콜 스택과 콜백 큐의 주요 차이점

구분콜 스택 (Call Stack)콜백 큐 (Callback Queue)

구분 콜 스택(Call Stack) 콜백 큐(Callback Queue)
구조 LIFO (Last In, First Out) FIFO (First In, First Out)
역할 현재 실행 중인 함수의 목록 관리 비동기 작업의 콜백 함수 대기
작동 방식 함수가 호출되면 스택에 쌓이고, 종료되면 제거됨 비동기 작업이 완료되면 콜백 큐에 추가되고, 콜 스택이 비어 있을 때 실행됨
우선순위 가장 최근에 호출된 함수가 먼저 실행 가장 먼저 추가된 콜백이 먼저 실행

➡️콜 스택과 콜백 큐는 자바스크립트의 비동기 프로그래밍에서 핵심적인 역할을 수행해요. 콜 스택은 현재 실행 중인 함수를 관리하고, 콜백 큐는 비동기 작업의 콜백 함수를 대기시켜, 이벤트 루프가 이 둘을 조정하며 효율적인 코드 실행을 가능하게 해요.

🛠 비동기 프로그래밍의 장점

  1. 성능 향상: 시간이 오래 걸리는 작업을 기다리지 않고, 다른 작업을 먼저 처리할 수 있어요.
  2. 효율적인 자원 사용: 자원을 효율적으로 활용할 수 있어, 병목 현상을 줄일 수 있어요.
  3. 유연한 코드 실행: 여러 작업을 비동기적으로 동시에 실행 가능해요.

정리

  • 자바스크립트는 기본적으로 단일 스레드이지만, 비동기 프로그래밍을 통해 여러 작업을 효율적으로 처리할 수 있어요.
  • 메모리 힙은 객체와 변수를 관리하고, 콜 스택은 함수 호출을 관리해요.
  • 이벤트 루프비동기 작업을 관리하여, 프로그램이 멈추지 않고 다른 작업을 실행할 수 있도록 도와줘요.