LoginSignup
23
21

More than 3 years have passed since last update.

Dartの非同期周り(async, await, then)

Posted at

Dartの非同期周りの挙動や使用どころについてのメモ。

基本的にDart(Flutter)はシングルスレッドで実装して、どうしても重い処理はIsolateやComputeを使用して別スレッドで処理することになる。
ただ単純なシングルスレッドだとネットワークレスポンスを待ったりする間にUIが固まってしまうので、Dartではイベントループを使用して非同期処理を実現している。
非同期処理の方法がasync,await,then辺りであり、それぞれの使い所や挙動の違いをまとめた。

async, await, thenの使い所

  • async: 非同期メソッドを定義する場合に使用する
  • await: 非同期メソッドの実行を待ってから以降の処理をしたい場合に使用する
  • then: 非同期メソッドの実行結果のコールバックを受け取って処理したい場合に使用する
    • thenの外に記述された処理はコールバックを待たずに実行されていく

動作検証

コード

test.dart
void main() async {
  print("001");
  returnTwo().then((value) {
    print(value);
  });
  print("003");
  var value = await returnFour();
  print(value);
  print("005");
}

Future<String> returnTwo() async {
  print("returnTwo");
  await Future.delayed(Duration(seconds: 2));
  return "002";
}

Future<String> returnFour() async {
  print("returnFour");
  await Future.delayed(Duration(seconds: 2));
  return "004";
}

実行結果

001
returnTwo
003
returnFour
002
004
005

解説

① 001: 普通に順番通り出力される
② returnTwo: returnTwo()がコールされてawaitされる前なので出力される
③ 003: main()が進んでいき003が出力される
④ returnFour: returnFour()がコールされてawaitされる前なので出力される
⑤ 002: returnTwo()の待ちが終了して002が出力される
⑥ 004: returnFour()の待ちが終了して004が出力される
⑦ 005: mainが進んでいき005が出力される

ポイント

② returnTwo()全体の実行が待たれるのではなくreturnTwo()内で待ちが発生する処理までは同期的に実行される
③ returnTwo()内部で待ちが発生するとmain()は進んでいく
⑦ main()はreturnFour()をawaitしているのでreturnFour()が完了するまで処理は進んでいかない

参考

https://medium.com/@jelenaaa.lecic/when-to-use-async-await-then-and-future-in-dart-5e00e64ab9b1
https://medium.com/@kawanojieee/dart-async-await-394846fb3d2c
https://medium.com/flutter-jp/isolate-a3f6eab488b5

23
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
21