전반적인 비동기 & 동기

2023-12-23

  • General
  • CS

이제는 익숙해졌겠지... 하면서 가끔씩 찾아봐야하는 간단한 비동기와 동기에 대한 내용입니다. 동기와 비동기 프로그래밍은 다음과 같이 정의할 수 있습니다:

동기 (Synchronous) 프로그래밍:

  • 동기 프로그래밍은 작업을 순차적으로 실행하고, 한 작업이 완료될 때까지 다음 작업을 기다립니다.
  • 작업이 완료될 때까지 다른 작업을 실행하지 않고, 블로킹될 수 있습니다.
  • 주로 간단한 프로그램 또는 순차적 작업에 사용됩니다.
  • 코드를 이해하고 디버깅하기 쉽습니다.

비동기 (Asynchronous) 프로그래밍:

  • 비동기 프로그래밍은 작업을 동시에 실행하고, 작업이 완료되지 않은 상태에서도 다른 작업을 실행할 수 있습니다.
  • 비동기 작업은 백그라운드 스레드 또는 이벤트 루프와 함께 사용되어 블로킹을 최소화합니다.
  • 주로 네트워크 호출, 파일 I/O, 사용자 인터페이스 이벤트 처리 등과 같이 오랜 시간이 걸리는 작업 또는 비동기 이벤트에 사용됩니다.
  • 코드를 작성 및 유지 보수하기 어려울 수 있으며, 콜백 헬(callback hell)과 같은 문제가 발생할 수 있습니다.

장단점:

동기 프로그래밍의 장점:

  1. 코드가 간단하고 직관적입니다.
  2. 디버깅이 상대적으로 쉽습니다.
  3. 동시성 문제로 인한 버그가 발생할 가능성이 낮습니다.

동기 프로그래밍의 단점:

  1. 오랜 시간이 걸리는 작업을 수행하는 경우, 애플리케이션의 반응성이 낮아질 수 있습니다.
  2. 여러 작업을 동시에 처리하는데 적합하지 않습니다.

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

  1. I/O 작업과 같은 블로킹 작업을 최소화하여 애플리케이션의 반응성을 향상시킵니다.
  2. 동시에 여러 작업을 처리할 수 있습니다.

비동기 프로그래밍의 단점:

  1. 코드가 복잡해지며, 콜백 지옥과 콜백 헬(callback hell)이 발생할 수 있습니다.
  2. 동기 프로그래밍보다 디버깅이 어렵습니다.
  3. 동시성 문제로 인한 버그가 발생할 가능성이 높아질 수 있습니다.

설명:

동기적 작업은 간단하며 순차적으로 진행되므로 코드를 이해하기 쉽습니다. 그러나 오랜 시간이 걸리는 작업의 경우 애플리케이션의 반응성을 저하시킬 수 있습니다.

비동기 작업은 애플리케이션의 반응성을 향상시킬 수 있지만, 콜백 함수와 비동기 이벤트 핸들링으로 인해 코드가 복잡해질 수 있습니다. 또한, 콜백 헬(callback hell)을 피하기 위한 프로미스, async/await 및 비동기 제어 라이브러리가 도입되어 코드를 관리하기 쉬워졌습니다.

JS 코드 예시 (비동기 프로그래밍):

// 비동기 작업
function fetchData() {
  return fetch('https://api.example.com/data')
    .then(response => response.json())
    .then(data => {
      console.log(data);
    })
    .catch(error => {
      console.error('Error:', error);
    });
}

fetchData();

제시한 JavaScript 코드는 비동기적으로 실행되는 예제입니다. 이 코드에서 fetch 함수는 비동기적으로 데이터를 가져옵니다. 비동기 작업은 다음과 같은 방식으로 동작합니다:

  1. fetch 함수는 네트워크 요청을 시작하고, 서버로부터 데이터를 가져오기 시작합니다.
  2. .then() 메서드는 fetch 작업이 완료되면 실행됩니다. 이 메서드는 첫 번째 인수로 성공 시 호출할 함수를 받고, 두 번째 인수로 실패 시 호출할 함수를 받습니다.
  3. 첫 번째 .then() 블록은 response => response.json() 콜백을 포함합니다. 이 부분은 HTTP 응답을 JSON으로 파싱하고 반환합니다. 이 부분은 fetch 작업이 완료되면 비동기적으로 실행됩니다.
  4. 두 번째 .then() 블록은 파싱된 데이터를 콘솔에 출력하는 부분입니다. 이 역시 비동기적으로 실행됩니다.
  5. .catch() 블록은 만약 어떤 이유에서든지 작업이 실패하면 실행되는 부분입니다.

전반적으로, 이 코드의 실행 흐름은 다음과 같습니다:

  • fetchData() 함수가 호출되면, fetch 함수가 네트워크 요청을 시작하고 제어를 fetch 함수 외부로 반환합니다.
  • 나중에 서버에서 응답이 오면, .then() 메서드에 지정된 콜백이 실행되며 데이터를 처리합니다.
  • 작업이 성공하거나 실패한 후에도 프로그램의 실행 흐름은 차단되지 않고 계속 진행됩니다. 이를 통해 애플리케이션은 다른 작업을 수행하거나 응답을 기다릴 필요 없이 계속 실행할 수 있습니다.

이러한 비동기 작업은 JavaScript에서 네트워크 요청, 파일 I/O, 타이머 및 이벤트 처리와 같은 블로킹 작업을 효과적으로 다룰 수 있도록 합니다.

fetch가 성공하면 연결된 모든 .then() 블록이 실행됩니다. Promise 체인에서 각 .then() 블록은 성공적으로 이전 단계를 마치면 비동기적으로 실행됩니다. 이것이 Promise 체인의 핵심 아이디어 중 하나입니다.

아래는 간단한 예시입니다:

fetch('https://api.example.com/data')
  .then(response => response.json()) // 첫 번째 .then()
  .then(data => {
    console.log('Data received:', data);
    // 다음 작업
  }) // 두 번째 .then()
  .then(() => {
    console.log('Another step'); // 세 번째 .then()
  });

위의 코드에서, fetch가 성공하면 첫 번째 .then() 블록이 실행되며, 그 결과에 따라 두 번째 .then() 블록이 실행됩니다. 두 번째 .then() 블록이 완료되면 세 번째 .then() 블록이 실행됩니다.

앞선 코드에서, 모든 .then() 블록이 성공적으로 이전 작업을 마치면 이후 단계가 실행됩니다. 이것이 Promises를 사용하여 비동기 작업을 연결하고 조절하는 핵심 아이디어입니다.


Python 코드 예시 (동기 프로그래밍):

# 동기 작업
import requests

def fetch_data():
    response = requests.get('https://api.example.com/data')
    data = response.json()
    print(data)

fetch_data()

비동기 작업에서는 fetch 함수가 백그라운드에서 데이터를 가져오고, 데이터가 도착하면 .then() 메서드를 사용하여 결과를 처리합니다. Python의 동기 코드에서는 requests 라이브러리를 사용하여 데이터를 동기적으로 가져옵니다.

추상클래스 & 인터...

포트 충돌 시 종료...