본문 바로가기
다트(Dart) 언어 강좌

비동기 프로그래밍을 알아보자

by everythingdev 2024. 7. 28.
반응형

비동기 프로그래밍 - Future와 async/await 완벽 가이드를 알아보자.

  • 플러터를 시작하기 전 다트(Dart) 언어의 개념에 대해 정리를 해보고자 합니다.
  • 다트(Dart) 언어 개념 정리 포스팅 후 플러터(Flutter) 개념 정리로 넘어갈 예정입니다.
  • 플러터(Flutter) 개념 정리 후 실습이 시작 된다고 보시면 될 것 같습니다.

소개

  • 현대 프로그래밍에서 비동기 처리는 필수적인 요소입니다.
  • 특히 모바일 앱이나 웹 애플리케이션 개발에서 사용자 경험을 향상시키기 위해 비동기 프로그래밍 기법을 자주 사용합니다.
  • 다트(Dart) 언어는 비동기 프로그래밍을 위한 강력한 도구인 Future와 async/await를 제공합니다.
  • 이번 포스팅에서는 다트의 비동기 프로그래밍에 대해 자세히 알아보겠습니다.

Future란?

Future는 다트에서 비동기 작업의 결과를 나타내는 객체입니다. 이는 '미래의 어느 시점에 완료될 계산'을 의미합니다. Future는 주로 시간이 오래 걸리는 작업, 예를 들어 네트워크 요청, 파일 입출력, 데이터베이스 쿼리 등에 사용됩니다.

  • Future는 다음 두 가지 상태 중 하나를 가집니다:
  1. 미완료(Uncompleted): 비동기 작업이 아직 완료되지 않은 상태
  2. 완료(Completed): 비동기 작업이 완료된 상태. 이때 결과값 또는 에러를 포함합니다.

Future를 사용하면 비동기 작업의 결과를 기다리는 동안 다른 작업을 수행할 수 있어 애플리케이션의 반응성을 높일 수 있습니다.

async와 await 키워드

async와 await 키워드는 비동기 코드를 동기 코드처럼 쉽게 작성할 수 있게 해주는 문법적 설탕(syntactic sugar)입니다.

  • async: 함수를 비동기 함수로 표시합니다. async 함수는 항상 Future를 반환합니다.
  • await: Future가 완료될 때까지 실행을 일시 중지합니다. await는 반드시 async 함수 내에서만 사용할 수 있습니다.

이 키워드들을 사용하면 비동기 코드의 가독성이 크게 향상되며, 콜백 지옥(callback hell)을 피할 수 있습니다.

Future 사용 예제

다음은 Future를 사용한 간단한 예제입니다:

Future<String> fetchUserOrder() {
  // 서버에서 사용자 주문을 가져오는 비동기 작업을 시뮬레이션합니다.
  return Future.delayed(Duration(seconds: 2), () => '라떼');
}

void main() {
  print('커피 주문을 시작합니다.');
  fetchUserOrder().then((order) {
    print('주문하신 $order가 준비되었습니다.');
  }).catchError((error) {
    print('주문 처리 중 오류가 발생했습니다: $error');
  }).whenComplete(() {
    print('주문 처리가 완료되었습니다.');
  });
  print('다른 작업을 수행합니다.');
}

  • 이 예제에서 fetchUserOrder 함수는 Future을 반환합니다. then 메서드를 사용하여 Future가 완료되었을 때 실행할 콜백을 등록합니다.
  • catchError는 오류 처리를, whenComplete는 작업 완료 후 항상 실행될 코드를 정의합니다.

async/await 사용 예제

위의 예제를 async/await를 사용하여 다시 작성해 보겠습니다:

Future<String> fetchUserOrder() {
  return Future.delayed(Duration(seconds: 2), () => '라떼');
}

Future<void> processOrder() async {
  try {
    print('커피 주문을 시작합니다.');
    String order = await fetchUserOrder();
    print('주문하신 $order가 준비되었습니다.');
  } catch (error) {
    print('주문 처리 중 오류가 발생했습니다: $error');
  } finally {
    print('주문 처리가 완료되었습니다.');
  }
}

void main() async {
  await processOrder();
  print('다른 작업을 수행합니다.');
}

  • async/await를 사용하면 코드가 더 읽기 쉽고 동기 코드와 유사한 흐름으로 작성할 수 있습니다. await 키워드는 Future의 결과를 기다리는 동안 함수의 실행을 일시 중지합니다.

에러 처리

  • 비동기 프로그래밍에서 에러 처리는 매우 중요합니다. Future를 사용할 때는 catchError 메서드를, async/await를 사용할 때는 try-catch 블록을 사용하여 에러를 처리할 수 있습니다.
Future<void> riskyOperation() async {
  try {
    String result = await someAsyncOperation();
    print('작업 결과: $result');
  } catch (e) {
    print('오류 발생: $e');
  }
}
  • 여러 개의 Future를 동시에 처리해야 할 때는 Future.wait를 사용할 수 있습니다:
Future<void> multipleAsyncOperations() async {
  try {
    List<String> results = await Future.wait([
      fetchData1(),
      fetchData2(),
      fetchData3(),
    ]);
    print('모든 작업 완료: $results');
  } catch (e) {
    print('하나 이상의 작업에서 오류 발생: $e');
  }
}

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

장점:

  1. 반응성 향상 : 시간이 오래 걸리는 작업을 백그라운드에서 처리하여 UI의 반응성을 유지할 수 있습니다.
  2. 리소스 효율성 : I/O 바운드 작업을 효율적으로 처리할 수 있어 시스템 리소스를 better하게 활용할 수 있습니다.
  3. 동시성 : 여러 작업을 동시에 처리할 수 있어 전체적인 성능이 향상됩니다.

단점:

  1. 복잡성 : 비동기 코드는 동기 코드에 비해 이해하고 디버깅하기 어려울 수 있습니다.
  2. 에러 처리 : 비동기 작업의 에러를 처리하는 것이 더 복잡할 수 있습니다.
  3. 학습 곡선 : 비동기 프로그래밍 개념을 이해하고 효과적으로 사용하는 데 시간이 걸릴 수 있습니다.

결론

  • 다트의 Future와 async/await는 비동기 프로그래밍을 위한 강력하고 유연한 도구입니다. 이들을 효과적으로 사용하면 반응성이 뛰어나고 효율적인 애플리케이션을 개발할 수 있습니다. 비동기 프로그래밍은 현대 소프트웨어 개발에서 필수적인 기술이므로, 다트 개발자라면 이 개념들을 숙지하고 실제 프로젝트에 적용하는 것이 중요합니다.
  • 비동기 프로그래밍을 마스터하기 위해서는 지속적인 연습과 실제 프로젝트에의 적용이 필요합니다. 다양한 시나리오에서 Future와 async/await를 사용해보고, 에러 처리 방법을 익히며, 동시성 처리 기법을 학습하세요. 이를 통해 더 효율적이고 사용자 친화적인 다트 애플리케이션을 개발할 수 있을 것입니다.
  • 추가 정보를 원하시거나 다트의 비동기 프로그래밍에 대해 더 자세히 알고 싶으시다면 질문해 주세요. 제가 도와드리겠습니다.

맺음말

  • 이번 포스팅에서는 다트의 비동기 프로그래밍에 대해 알아보았습니다.
  • 다음 포스팅에서는 다트의 스트림과 iterable에 대해 알아보고자 합니다.
반응형