Flutter

Dart async awaitの使い方|Futureを順番に待つ基本を初心者向けに解説

Dartのasync/awaitを初心者向けに解説します。Futureとthenの関係、awaitで待つ書き方、try-catch、Future.wait、Flutterでローディング表示につなげる考え方を整理します。

この記事の目次
  1. この記事の結論
  2. async/awaitとは何か
  3. 基本の書き方
  4. Futureとthenの関係
  5. エラーをtry-catchで扱う
  6. 複数の非同期処理を待つ
  7. Flutterで使うときの考え方
  8. よくあるつまずき
  9. 次に読む記事
  10. まとめ

Dartのasync/awaitは、通信、ファイル読み込み、時間のかかる処理を順番に読みやすく書くための仕組みです。FlutterではAPI取得やFirebase処理でほぼ必ず使います。

この記事の結論

asyncは「この関数は非同期処理を含む」と宣言する印、awaitは「Futureの結果が返るまで待つ」ための印です。まずはFuture、async、await、try-catchの4つだけ押さえれば実装を始められます。

async/awaitとは何か

Dartでは、すぐに値が返らない処理をFutureで表します。asyncを付けた関数の中ではawaitが使えるようになり、Futureの結果を通常の値のように受け取れます。

Future<String> loadUserName() async {
  await Future.delayed(const Duration(seconds: 1));
  return "Sato";
}

基本の書き方

async関数を呼び出す側も、結果を待ちたい場合はawaitを使います。main関数でもasyncを付けられます。

Future<void> main() async {
  final name = await loadUserName();
  print("Hello, $name");
}

Futureとthenの関係

Futureは「あとで完了する処理の結果」を表す型です。async/awaitを使わずthen()で完了後の値を受け取ることもできますが、処理が増えるとネストしやすいため、実務ではasync/awaitの方が読みやすいことが多いです。

// then で受け取る書き方
loadUserName().then((name) {
  print(name);
});

// await で受け取る書き方(同じ意味・こちらが読みやすい)
final name = await loadUserName();
print(name);

エラーをtry-catchで扱う

API通信では失敗が起きる前提で書きます。awaitしている処理が例外を投げた場合はtry-catchで受け取ります。

Future<void> main() async {
  try {
    final name = await loadUserName();
    print(name);
  } catch (error) {
    print("読み込みに失敗しました: $error");
  }
}

複数の非同期処理を待つ

順番に実行したい場合はawaitを並べます。同時に実行してまとめて待ちたい場合はFuture.waitを使います。

final results = await Future.wait([
  loadUserName(),
  loadUserName(),
]);
print(results);

Flutterで使うときの考え方

Flutterでは、ボタンを押したときにasync関数を呼び、開始時にローディング状態をtrue、完了時にfalseへ戻す形がよく使われます。UIの再描画にはsetStateや状態管理ライブラリを組み合わせます。

よくあるつまずき

  • awaitを書けるのはasync関数の中だけ
  • async関数は戻り値がFutureになる
  • 通信処理ではtry-catchを省略しない
  • UIでは待っている間のローディング表示を用意する

次に読む記事

まとめ

async/awaitは、Futureを読みやすく扱うための基本文法です。API取得やFirebase処理へ進む前に、await、try-catch、Future.waitを小さなコードで確認しておきましょう。