기억을 지배하는 기록

Dart 비동기 프로그래밍 본문

Flutter for Beginners

Dart 비동기 프로그래밍

Andrew's Akashic Records 2025. 2. 28. 17:58
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
Comments