はじめに
本記事では複数のAPIを非同期で並列実行したい時などに使用するFuture.wait()
についてつらつらと書いています。
並列処理を行いたい場合、またそのエラーハンドリングで困っている場合にご活用ください。
Flutterの非同期処理について
まずそもそも非同期処理とはある処理が終わるのを待たずに、別の処理を実行すること
です。
そのため、『ユーザーエクスペリエンス向上』『リソース効率化』など様々なメリットがあります。
Flutterの基本的な非同期処理は以下の通り
import 'dart:async';
// 非同期関数の定義
Future<void> fetchData() async {
// 非同期処理の実行
try {
// ネットワークリクエストなどの非同期処理をawaitキーワードで待機する
var result = await http.get('https://hogehoge');
// 非同期処理が完了した後の処理を記述する
} catch (e) {
// エラーハンドリング
}
}
// メイン関数
void main() {
// fetchData関数を非同期的に実行する
fetchData();
}
非同期処理を並列実行とエラーハンドリング
いくつかの非同期処理を並列実行する際はFuture.wait()
を使用します
以下のコードではfetchData1()
fetchData2()
を並列で実行しその完了を待ちます。
Future<void> fetchData1() async {
try {
// fetchData1非同期処理
} catch (e) {
rethrow;
}
}
Future<void> fetchData2() async {
try {
// fetchData2非同期処理
} catch (e) {
rethrow;
}
}
Future<void> main() async {
try {
// 並列実行する非同期処理をリストに格納
List<Future<void>> futures = [fetchData1(), fetchData2()];
// Future.waitを使用して並列実行し、完了を待機
await Future.wait(futures);
} catch (e) {
// ※エラーハンドリング
}
}
ただしfetchData1()
fetchData2()
でエラーが発生し、rethrow
してもmain()
でハンドリングされません → ここがつまづいたポイント
.then()や.catchError()などでチェインさせる必要があります。
そのためmain()
で正しくハンドリングすることを考慮した最終的な形は次のようになります
Future<void> fetchData1() async {
try {
// fetchData1非同期処理
} catch (e) {
rethrow;
}
}
Future<void> fetchData2() async {
try {
// fetchData2非同期処理
} catch (e) {
rethrow;
}
}
Future<void> main() async {
try {
// 並列実行する非同期処理をリストに格納
List<Future<void>> futures = [fetchData1(), fetchData2()];
// Future.waitを使用して並列実行し、完了を待機
await Future.wait(futures, eagerError: true)
.then(() => {
// 完了後の処理
}, onError: (Object e) => {throw e})
.catchError((Object e) => throw e);
} catch (e) {
// エラーハンドリング
}
}
eagerError
をtrueにすると、futures
の中から最初のエラーが発生した場合、即座にエラーとして完了します。そのため本例のように複数の非同期処理に対して同一のエラーハンドリングを行う際などにはこちらが適しています。
こちらでエラーハンドリングも含めた非同期処理の並列実行の例は以上です!
参考