dart:async 라이브러리

dart:async는 Dart 비동기 프로그래밍의 핵심 기능인 Future, Stream을 제공합니다.

  1. Future / Stream을 사용한다고 해서 반드시 dart:async를 직접 가져올 필요는 없습니다. dart:core에서 이미 내보내고 있습니다;
  2. StreamControllerStreamSubscriptionParallelWaitError 등 타입을 이용하려면 명시적으로 가져와야 합니다:
import 'dart:async';Code language: JavaScript (javascript)

두 가지 핵심 개념:

  • Future단 한 번 발생하는 비동기 결과를 표현합니다(어느 시점에 단 하나의 값 또는 오류만 생성)
  • Stream연속적인 일련의 비동기 데이터를 표현합니다(값을 계속 여러 개 생성하며 이벤트 흐름과 유사)

Future

1. async / await

가장 권장하는 방식으로, .then() 체인 호출보다 가독성이 좋습니다

  • async로 표시한 함수는 Future를 반환합니다;
  • await는 Future가 완료될 때까지 기다리며 결과가 반환될 때까지 현재 코드 실행을 멈춥니다;
  • try-catch로 비동기 예외를 포착할 수 있습니다.
// async 函数返回 Future
Future<String> findEntryPoint() async => "main.dart";
Future<int> runExecutable(String entry, List args) async => 0;
Future<void> flushThenExit(int code) async {}

// await 写法(推荐)
Future<void> runUsingAsyncAwait() async {
  try {
    var entryPoint = await findEntryPoint();
    var exitCode = await runExecutable(entryPoint, []);
    await flushThenExit(exitCode);
  } catch (e) {
    // 统一捕获异常
    print("出错:$e");
  }
}Code language: JavaScript (javascript)

2. .then() / .catchError() 전통적인 체인 방식

  • .then():Future가 정상 완료된 뒤 콜백을 실행하며 새로운 Future를 반환해 계속 체인 연결 가능
  • .catchError():예외를 포착합니다; 반드시 then의 반환값 뒤에 연결해야 then 내부 예외까지 잡을 수 있습니다
void runUsingFuture() {
  findEntryPoint()
      .then((entryPoint) {
        return runExecutable(entryPoint, []);
      })
      .then(flushThenExit)
      .catchError((e) {
        print("异常:$e");
      });
}Code language: JavaScript (javascript)

3. 여러 동시 실행 Future 기다리기

① Future.wait()

모든 작업이 끝날 때까지 대기; 어느 한 Future라도 오류가 발생하면 전체가 실패합니다

Future<void> task1() async {}
Future<void> task2() async {}
Future<void> task3() async {}

void testWait() async {
  await Future.wait([
    task1(),
    task2(),
    task3(),
  ]);
  print("全部任务执行完成");
}Code language: JavaScript (javascript)
② List.wait / Record.wait(신기능, 동시 작업 오류 정밀 처리)

ParallelWaitError를 발생시키며 어느 것은 성공하고 어느 것은 실패했는지 구분할 수 있으며 서로의 실행을 방해하지 않습니다.

Future<int> delete() async => 1;
Future<String> copy() async => "ok";
Future<bool> errorTask() async {
  throw Exception("任务失败");
}

void main() async {
  try {
    // 列表形式
    var results = await [delete(), copy(), errorTask()].wait;
  } on ParallelWaitError<List<Object?>, List<AsyncError?>> catch (e) {
    print(e.values);   // 成功有值,失败为null
    print(e.errors);   // 成功为null,失败存放错误信息
  }

  // Record元组形式:支持不同类型Future
  try {
    final (resInt, resStr, resBool) = await (delete(), copy(), errorTask()).wait;
  } on ParallelWaitError<(int?, String?, bool?), (AsyncError?, AsyncError?, AsyncError?)> catch(e) {

  }
}Code language: JavaScript (javascript)

Stream

Stream은 연속한 일련의 비동기 데이터를 나타냅니다(파일 한 줄씩 읽기, 버튼 클릭 이벤트, 네트워크 데이터 흐름 등).

두 가지 사용 방식

1:await for 비동기 for 반복문(간결하며 동기식 순회와 유사)

유한한 데이터 흐름에 적합; 무한히 지속되는 이벤트 흐름(페이지 클릭 이벤트 등)에는 사용하지 마세요. 이후 코드가 차단됩니다.

import 'dart:io';

Future<void> readFileByAwaitFor() async {
  var file = File("config.txt");
  Stream<List<int>> input = file.openRead();
  var lines = input
      .transform(utf8.decoder)
      .transform(const LineSplitter());

  try {
    await for (final line in lines) {
      print("读取一行:$line");
    }
    print("文件读取完毕");
  } catch (e) {
    print("读取异常 $e");
  }
}Code language: PHP (php)
2 .listen() 구독 감시(무한 이벤트 흐름에 적합)
inputStream.listen(
  (data) {
    // 收到数据回调
  },
  onError: (err) {
    // 发生错误
  },
  onDone: () {
    // 流正常关闭完成
  },
);Code language: JavaScript (javascript)

listen은 StreamSubscription을 반환하며 .cancel()로 구독을 취소할 수 있습니다.

자주 쓰이는 Stream 연산 메서드

  • 필터링:where()
  • 데이터 제한:take()takeWhile()
  • 데이터 건너뛰기:skip()skipWhile()
  • 단일 요소 가져오기:firstlastsinglefirstWhere()

Stream 데이터 변환 transform()

변환기를 통해 스트림 데이터 타입을 변경합니다(대표적인 예: 바이너리 스트림을 문자열로 변환)

var lines = inputStream
    .transform(utf8.decoder)       // List<int> → String
    .transform(const LineSplitter()); // String → 逐行字符串Code language: JavaScript (javascript)

listen() vs await for 선택 가이드

  1. 파일 읽기, 유한한 시퀀스 데이터 → await for
  2. UI 이벤트, 지속 메시지 전달 등 무한 스트림.listen()
  3. await for가 시작되면 스트림이 끝날 때까지 대기하므로 무한 이벤트 스트림은 프로그램 정지 원인이 됩니다

dart:async 라이브러리

Previous:

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다