본문 바로가기
Flutter for Beginners

Dart 비동기 프로그래밍

by Andrew's Akashic Records 2025. 2. 28.
728x90

Dart

Dart 비동기 프로그래밍 (Asynchronous Programming)

Dart는 비동기 프로그래밍(Asynchronous Programming)을 지원하여 네트워크 요청, 파일 읽기, 데이터베이스 작업과 같이 시간이 걸리는 작업을 효율적으로 처리할 수 있습니다.

 

Dart의 비동기 프로그래밍 핵심 요소:

  • Future: 비동기 작업을 나타내는 객체
  • async & await: 비동기 함수 정의 및 실행
  • Stream: 여러 개의 비동기 데이터를 순차적으로 처리

1. Future란?

  • Future는 미래에 완료될 값(비동기 작업의 결과)을 나타내는 객체
  • 시간이 걸리는 작업이 완료되면 결과 값을 반환하거나 예외를 발생
  • Future는 단일 값을 반환함 (여러 값 처리 시 Stream 사용)

1.1. Future 기본 사용법

Future<String> fetchData() {
  return Future.delayed(Duration(seconds: 2), () {
    return "데이터 로드 완료!";
  });
}

void main() {
  fetchData().then((data) {
    print(data); // 2초 후 "데이터 로드 완료!" 출력
  });

  print("로딩 중..."); // 즉시 실행
}
로딩 중...
(2초 후)
데이터 로드 완료!
  • 비동기 작업이 완료되면 .then()을 통해 결과를 처리할 수 있음

1.2. Future의 catchError()를 사용한 예외 처리

Future<String> fetchData() {
  return Future.delayed(Duration(seconds: 2), () {
    throw "데이터 가져오기 실패!"; // 오류 발생
  });
}

void main() {
  fetchData()
      .then((data) => print(data))
      .catchError((error) => print("오류 발생: $error"));

  print("로딩 중...");
}
로딩 중...
(2초 후)
오류 발생: 데이터 가져오기 실패!
  • catchError()를 사용하여 비동기 작업 중 발생한 오류를 처리할 수 있음

2. async & await 사용

  • async 함수 내부에서 await을 사용하면 비동기 작업이 완료될 때까지 기다린 후 실행됨
  • await을 사용하면 코드를 동기 방식처럼 작성 가능

2.1. async와 await 기본 사용법

Future<String> fetchData() async {
  await Future.delayed(Duration(seconds: 2));
  return "데이터 로드 완료!";
}

void main() async {
  print("로딩 중...");
  String data = await fetchData();
  print(data);
}
로딩 중...
(2초 후)
데이터 로드 완료!
  • await fetchData();는 비동기 작업이 완료될 때까지 대기

2.2. try-catch를 사용한 예외 처리

Future<String> fetchData() async {
  await Future.delayed(Duration(seconds: 2));
  throw "데이터 가져오기 실패!"; // 오류 발생
}

void main() async {
  print("로딩 중...");

  try {
    String data = await fetchData();
    print(data);
  } catch (e) {
    print("오류 발생: $e");
  }
}
로딩 중...
(2초 후)
오류 발생: 데이터 가져오기 실패!
  • try-catch를 사용하면 비동기 함수에서 발생한 오류를 안전하게 처리할 수 있음

3. Future.wait()을 사용한 여러 개의 비동기 작업 실행

Future.wait()은 여러 개의 Future를 동시에 실행하고, 모든 작업이 완료될 때까지 기다립니다.

Future<String> fetchUser() async {
  await Future.delayed(Duration(seconds: 2));
  return "사용자 데이터";
}

Future<String> fetchPosts() async {
  await Future.delayed(Duration(seconds: 3));
  return "게시글 데이터";
}

void main() async {
  print("데이터 불러오는 중...");

  List<String> results = await Future.wait([fetchUser(), fetchPosts()]);

  print(results[0]); // 사용자 데이터
  print(results[1]); // 게시글 데이터
}
데이터 불러오는 중...
(2초 후) 사용자 데이터
(3초 후) 게시글 데이터
  • 여러 개의 Future를 병렬로 실행하여 시간을 단축할 수 있음

4. Stream: 여러 개의 비동기 데이터 처리

  • Future는 단일 값 반환, Stream은 여러 개의 값을 순차적으로 반환
  • 이벤트(데이터 스트림)가 발생할 때마다 값을 받을 수 있음

4.1. Stream 기본 사용법

Stream<int> numberStream() async* {
  for (int i = 1; i <= 5; i++) {
    await Future.delayed(Duration(seconds: 1));
    yield i; // 데이터 반환
  }
}

void main() async {
  print("스트림 시작...");

  await for (int value in numberStream()) {
    print("받은 값: $value");
  }

  print("스트림 종료!");
}
스트림 시작...
(1초 후) 받은 값: 1
(1초 후) 받은 값: 2
(1초 후) 받은 값: 3
(1초 후) 받은 값: 4
(1초 후) 받은 값: 5
스트림 종료!
  • await for를 사용하면 Stream 데이터를 쉽게 처리할 수 있음

4.2. listen()을 사용하여 Stream 구독

void main() {
  Stream<int> stream = Stream.periodic(Duration(seconds: 1), (x) => x).take(5);

  stream.listen(
    (data) => print("받은 값: $data"),
    onDone: () => print("스트림 종료!"),
  );
}
(1초 후) 받은 값: 0
(1초 후) 받은 값: 1
(1초 후) 받은 값: 2
(1초 후) 받은 값: 3
(1초 후) 받은 값: 4
스트림 종료!
  • listen()을 사용하면 비동기 데이터를 실시간으로 처리 가능

5. Completer를 사용하여 커스텀 비동기 작업 생성

Completer를 사용하면 수동으로 Future를 완료시킬 수 있습니다.

import 'dart:async';

Future<String> loadData() {
  Completer<String> completer = Completer();

  Future.delayed(Duration(seconds: 2), () {
    completer.complete("데이터 로드 완료!"); // Future 완료
  });

  return completer.future;
}

void main() async {
  print("로딩 중...");
  String result = await loadData();
  print(result);
}
로딩 중...
(2초 후)
데이터 로드 완료!
  • Completer는 수동으로 Future를 제어할 때 사용됨

6. Dart 비동기 프로그래밍 정리

개념 설명
Future 단일 비동기 작업 수행
.then() Future 결과를 처리
async / await 비동기 작업을 동기 코드처럼 작성
try-catch 예외 처리
Future.wait() 여러 개의 Future 동시 실행
Stream 여러 개의 비동기 데이터 처리
await for Stream 데이터를 반복적으로 처리
listen() Stream을 구독하여 실시간 데이터 처리

 

728x90