👌
Dartの非同期処理・並行/並列/await/unawaited 完全ガイド
Flutter/Dartで非同期処理を書くとき、Future
や async/await
を何となく使っている人も多いのでは?
この記事では、
- Dartのスレッドモデル
- 並行処理と並列処理の違い
- イベントループの仕組み
-
await
/unawaited
の意味と使い分け - エラー補足・Linter対応
これらすべてを図解・コード付きで一気に理解します。
Dartはシングルスレッドなのか?
- 通常は シングルスレッド(メインIsolate) で動く
- ただし、
Isolate
を使えば別スレッドで並列処理が可能
処理種別 | Dartでの実装例 |
---|---|
並行処理 |
Future , async/await
|
並列処理 |
Isolate.run() , Isolate.spawn()
|
💡 Isolateはメモリ共有しない
- Dartの
Isolate
は スレッドのように並列実行できるが、メモリは完全に分離 されています - 通常のマルチスレッド言語(Java/C++など)と異なり、グローバル変数・共有オブジェクトを使ってやり取りはできない
- 代わりに
SendPort
/ReceivePort
を使ってメッセージで通信 します
比較表:Isolate vs マルチスレッド
項目 | Isolate (Dart) | マルチスレッド (Java等) |
---|---|---|
実行単位 | 別スレッド(別Isolate) | スレッド |
メモリ共有 | ❌ 共有しない(コピー or Port) | ✅ 共有される(ロックが必要) |
通信方法 | メッセージ(SendPort) | 共有変数・ロック |
安全性 | ✅ データ競合なし | ❌ 競合やバグに注意 |
→ Dartでは「安全性のためにメモリをあえて分離」している
並行処理と並列処理の違い
用語 | 意味 | Dartでの例 |
---|---|---|
並行処理 | 複数の処理を"同時に扱っているように"見せる(実行は順番) |
Future , async/await
|
並列処理 | 複数の処理を"物理的に同時に"実行 |
Isolate (スレッド相当) |
Futureは裏で処理しているのか?
-
Future(...)
は イベントキューに登録される - すぐ実行されるのではなく、"後で順番に処理される"
- つまり「裏で同時に」ではなく、「後で一つずつ」
print("A");
Future(() => print("B"));
print("C");
出力:
A
C
B
イベントループの仕組み
イベントループでは次の順で処理されます:
- 同期処理
- マイクロタスクキュー(
scheduleMicrotask
など) - イベントキュー(
Future
,Future.delayed
など)
await
をつけると、その処理の完了を待ってから次に進みます。
unawaited
を使うと、待たずに次の処理に進みつつも、実行だけはされるということになります。
await
と unawaited
の使い分け
await |
unawaited(...) |
|
---|---|---|
完了を待つ? | ✅ 待つ | ❌ 待たない |
エラーを補足できる? | ✅ try-catch 可能 |
❌ .catchError() が必要 |
Linter対応 | ✅ 問題なし | ✅ 意図明示でOK |
用途 | API通信、UI操作 | ログ送信、通知送信など |
await
なしで放置すると?
❌ someAsyncFunc(); // ← 警告&エラー握りつぶしの可能性
unawaited
を使えば安全
✅ unawaited(someAsyncFunc());
✅ エラーを補足したいなら:
unawaited(
someAsyncFunc().catchError((e) {
print("ログ送信失敗: $e");
}),
);
try-catch
の効き方に注意!
try {
someAsyncFunc(); // ← awaitしてないのでcatch効かない!
} catch (e) {
print("捕まらない");
}
try {
await someAsyncFunc(); // ← awaitすればcatchできる!
} catch (e) {
print("✅ 捕まえた");
}
まとめ:実務での使い分けフロー
Q1. この処理、完了しないと困る?
→ Yes → await
→ No → Q2
Q2. Linter警告を回避したい?
→ Yes → unawaited(...)
→ No → 書いたFutureは必ず補足・管理すべし!
おわりに
- Dartの非同期処理はシンプルに見えて奥が深い
-
await
/unawaited
を正しく使い分けて、エラー・順序・Linter対応もすべて制御可能にしよう!
Discussion