はじめに
DartやFlutterで開発していると、Future というクラスを頻繁に目にします。
ネットワーク通信やファイル読み込みなど、「今すぐには結果が得られない処理」を扱うときに欠かせないのが Future です。
この記事では、
-
Futureの基本概念 - 状態とライフサイクル
-
then()・async/awaitの使い方 - エラー処理と複数Futureの並行実行
までを順に整理していきます。
Futureとは何か?
Future は「将来得られる値(結果)」を表すクラスです。
非同期処理の結果を 「約束(Promise)」 のようにラップします。
Future<int> fetchData() async {
await Future.delayed(Duration(seconds: 2));
return 42;
}
この関数はすぐに値を返しません。
2秒後に「42」を返す Future<int> オブジェクトを返します。
Futureのライフサイクル
| 状態 | 意味 |
|---|---|
| 未完了 (Uncompleted) | 処理がまだ終わっていない |
| 完了(成功)(Completed with value) | 結果が返された |
| 完了(失敗)(Completed with error) | エラーで終了した |
final future = fetchData(); // 状態: 未完了
future.then((value) => print('結果: $value')); // 完了したら呼ばれる
then()による結果の取得
Future.then() を使うと、完了時の処理を登録できます。
fetchData()
.then((value) {
print('取得結果: $value');
})
.catchError((error) {
print('エラー発生: $error');
});
-
then()→ 成功時に呼ばれる -
catchError()→ 失敗時に呼ばれる
async / await構文
then() チェーンは読みにくくなりがちです。
そのため Dart では async / await を使って、同期的な書き方ができます。
void main() async {
try {
final result = await fetchData();
print('結果: $result');
} catch (e) {
print('エラー: $e');
}
}
await は 「Futureの完了を待って次の行に進む」 という意味です。
エラー処理
Futureがエラーで完了した場合、catchError() または try-catch で処理します。
Future<void> riskyOperation() async {
throw Exception('失敗しました');
}
void main() async {
try {
await riskyOperation();
} catch (e) {
print('エラーを捕捉: $e');
}
}
複数のFutureを並行実行する — Future.wait()
複数の非同期処理を同時に実行して、すべて完了するまで待つこともできます。
final results = await Future.wait([
fetchData(),
Future.delayed(Duration(seconds: 1), () => 10),
]);
print(results); // [42, 10]
Future.wait()は「全てのFutureが完了したときに、リストで結果を返す」。
チェーンと変換
then() を使えば、Futureの結果を次のFutureに渡す連鎖処理も可能です。
Future<int> doubleValue(int x) async => x * 2;
fetchData()
.then(doubleValue)
.then((v) => print('倍の値: $v'))
.catchError((e) => print('エラー: $e'));
Futureの型と戻り値
Future<T> の <T> は戻り値の型を表します。
| 関数の戻り値 | 意味 |
|---|---|
Future<int> |
将来 int が返る |
Future<void> |
値を返さない(ただ完了を待つ) |
Future<List<String>> |
将来 List<String> が返る |
実践例:API通信をシミュレート
Future<String> fetchUserName() async {
await Future.delayed(Duration(seconds: 2));
return "Anna";
}
Future<int> fetchUserAge() async {
await Future.delayed(Duration(seconds: 3));
return 28;
}
void main() async {
print("取得中...");
final results = await Future.wait([
fetchUserName(),
fetchUserAge(),
]);
print("ユーザー: ${results[0]}(${results[1]}歳)");
}
出力:
取得中...
ユーザー: Anna(28歳)
まとめ
| 概念 | 説明 |
|---|---|
Future |
将来完了する非同期処理の結果を表す |
then() |
完了後に実行するコールバックを登録 |
await |
Futureが完了するまで待機する |
catchError / try-catch
|
エラー処理 |
Future.wait() |
複数の非同期処理を同時に待つ |