본문 바로가기
Flutter for Beginners

Dart Completer (커스텀 비동기 처리)

by Andrew's Akashic Records 2025. 3. 4.
728x90

Dart

Dart Completer (커스텀 비동기 처리)

Dart에서 Completer 는 Future를 수동으로 제어할 수 있는 객체입니다.
즉, 비동기 작업을 직접 완료하거나, 실패 처리할 때 사용됩니다.

1. Completer란?

  • Future는 일반적으로 비동기 작업이 자동으로 완료되지만,
  • Completer를 사용하면 개발자가 Future를 수동으로 완료(complete)하거나 오류 처리(completeError)할 수 있음.
  • 비동기 작업의 흐름을 개발자가 직접 제어할 때 유용.

2. Completer 기본 사용법

2.1. Completer를 사용하여 비동기 데이터 반환

import 'dart:async';

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

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

  return completer.future;
}

void main() async {
  print("로딩 중...");
  String result = await fetchData();
  print(result);
}
로딩 중...
(2초 후)
데이터 로드 완료!
  • Completer를 사용하면 Future가 언제 완료될지 직접 제어 가능

2.2. Completer를 사용한 오류 처리 (completeError)

import 'dart:async';

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

  Future.delayed(Duration(seconds: 2), () {
    completer.completeError("데이터 가져오기 실패!"); // 오류 발생
  });

  return completer.future;
}

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

  try {
    String result = await fetchDataWithError();
    print(result);
  } catch (e) {
    print("오류 발생: $e");
  }
}
로딩 중...
(2초 후)
오류 발생: 데이터 가져오기 실패!
  • completeError()를 사용하면 수동으로 Future의 오류를 발생시킬 수 있음

3. Completer의 활용 예제

3.1. Completer를 사용하여 HTTP 요청 처리

Dart의 http 패키지를 사용하여 비동기 네트워크 요청을 Completer로 처리할 수 있습니다.

import 'dart:async';
import 'package:http/http.dart' as http;

Future fetchDataFromApi() {
  Completer completer = Completer();

  http.get(Uri.parse("https://jsonplaceholder.typicode.com/todos/1")).then((response) {
    if (response.statusCode == 200) {
      completer.complete(response.body);
    } else {
      completer.completeError("API 요청 실패: ${response.statusCode}");
    }
  });

  return completer.future;
}

void main() async {
  print("API 요청 중...");

  try {
    String data = await fetchDataFromApi();
    print("API 응답: $data");
  } catch (e) {
    print("오류 발생: $e");
  }
}
  • API 요청의 성공/실패 여부를 Completer를 사용해 수동으로 처리 가능
http 패키지 설치하기


1. pubspec.yaml 파일 수정

dependencies:
  http: ^1.3.0  # 또는 최신 버전

 

최신 버전 확인을 원하면 다음 링크에서 확인하세요: https://pub.dev/packages/http

2. 테미널에서 패키지 설치
dart pub get​

3.2. Completer를 사용하여 사용자 입력 대기

사용자의 입력을 비동기적으로 받아야 할 때 Completer를 활용하면 편리합니다.

import 'dart:async';
import 'dart:io';

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

  print("이름을 입력하세요:");
  stdin.readLineSync(); // 동기 입력

  Future.delayed(Duration(seconds: 1), () {
    completer.complete("사용자 입력 완료!");
  });

  return completer.future;
}

void main() async {
  print("입력 대기 중...");
  String result = await getUserInput();
  print(result);
}
  • 사용자의 입력을 받는 동안 다른 작업을 수행할 수 있음

3.3. Completer를 사용한 비동기 타이머

비동기적으로 특정 시간이 지나면 완료되는 작업을 Completer로 만들 수 있습니다.

import 'dart:async';

Future<void> delayedTask(int seconds) {
  Completer<void> completer = Completer();

  Timer(Duration(seconds: seconds), () {
    print("$seconds초 후 작업 완료!");
    completer.complete();
  });

  return completer.future;
}

void main() async {
  print("작업 시작...");
  await delayedTask(3);
  print("모든 작업 완료!");
}
작업 시작...
(3초 후)
3초 후 작업 완료!
모든 작업 완료!
  • 특정 시간이 지나면 완료되는 Future를 생성할 수 있음

4. Completer와 StreamController 비교

기능 Completer StreamController
데이터 처리 단일 값 (한 번만 완료) 여러 개의 데이터 처리 가능
용도 비동기 작업 수동 완료 실시간 데이터 스트리밍
데이터 추가 방식 complete() 사용 sink.add() 사용
예제 API 요청, 비동기 작업 WebSocket, 실시간 데이터
  • Completer는 단일 비동기 작업을 제어할 때 사용
  • StreamController는 연속적인 데이터 스트리밍이 필요할 때 사용

Completer 요약

기능 설명
Completer 생성 Completer<Type> completer = Completer();
Future 반환 completer.future;
complete() 사용 completer.complete("완료됨");
completeError() 사용 completer.completeError("오류 발생");
활용 예제 API 요청, 사용자 입력 대기, 타이머 작업

 

728x90