👌

Dartの非同期処理・並行/並列/await/unawaited 完全ガイド

に公開

Flutter/Dartで非同期処理を書くとき、Futureasync/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

イベントループの仕組み

イベントループでは次の順で処理されます:

  1. 同期処理
  2. マイクロタスクキュー(scheduleMicrotaskなど)
  3. イベントキュー(Future, Future.delayedなど)

await をつけると、その処理の完了を待ってから次に進みます。

unawaited を使うと、待たずに次の処理に進みつつも、実行だけはされるということになります。


awaitunawaited の使い分け

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