Flatter(dart)の非同期処理、(async/await)の挙動を確かめる

Flutterっていうかdartの同期処理がよくわからなくなったんで、思いつくパターンを書いてみて、挙動を把握し、金輪際、同期処理での失敗とはおさらばします!

処理に時間がかかる関数を使う時、作った時の扱い方の参考になると思います。

 

今回挙動を試す関数は以下の4通りです。

void f1() {
// 遅れて処理だけするfutureインスタンスを返さない
Future.delayed(Duration(seconds: 1), () {
print("f1");
});
}

void f2() {
// 遅れてStringを返してくれるfutureインスタンスを返さない
Future.delayed(Duration(seconds: 1), () {
return "f2";
});
}

Future<void> f3() {
// 遅れて処理だけするfutureインスタンスを返す
return Future.delayed(Duration(seconds: 1), () {
print("f3");
});
}

Future<String> f4() {
// 遅れてStringを返してくれるfutureインスタンスを返す
return Future.delayed(Duration(seconds: 1), () {
return "f4";
});
}

それぞれasync/awaitを付ける/付けないの2通りで試すので、計8通りの結果が正しく予測できたらこの記事は読まなくて大丈夫です笑

(そもそもflutterの同期処理はfuture/thenでも書けますが、ネストが深くなっちゃうのでawait/asyncを使う方が良いらしいので、こちらで書きます) 

 

f1・・・遅れて処理だけする関数で、値を返さない関数です。

void f1() {
// 遅れて処理だけするfutureインスタンスを返さない
Future.delayed(Duration(seconds: 1), () {
print("f1");
});
}

await 実行関数 結果

awaitなし

同期的)

main() {
  print("start");
  f1();
  print("end");
}
start
end
f1

awaitあり

(非同期)

Future<void> main() async {
  print("start");
  await f1();
  print("end");
}
start
end
f1


実行側でasync/awaitを付けようが付けまいが、処理は待ってもらえません。

 

 f2・・・遅れてStringを返してくれるfutureインスタンスを返さない。

void f2() {
// 遅れてStringを返してくれるfutureインスタンスを返さない
Future.delayed(Duration(seconds: 1), () {
return "f2";
});
}

await 実行関数 結果

awaitなし

(同期的)

main() {
  print("start");
  f2();
  print("end");
}
start
end

await

(非同期)

Future<void> main() async {
  print("start");
  await f2();
  print("end");
}
start
end

 

mainからすると値を返して来ないし、処理もしてないので無意味な呼び出しとなります。

 

f3・・・遅れて処理だけするfutureインスタンスを返す

Future<void> f3() {
// 遅れて処理だけするfutureインスタンスを返す
return Future.delayed(Duration(seconds: 1), () {
print("f3");
});
}

await 実行関数 結果

awaitなし

(同期的)

main() {
  print("start");
  f3();
  print("end");
}
start
end
f3

awaitあり

(非同期)

Future<void> main() async {
  print("start");
  await f3();
  print("end");
}
start
f3
end

 

futureインスタンスが返って来る時に、mainでasync/awaitをつけるとそのfutureインスタンスの処理が完了するのを待ってからmainの以降の処理に取り掛かります。

 

f4・・・遅れてStringを返してくれるfutureインスタンスを返す

Future<String> f4() {
// 遅れてStringを返してくれるfutureインスタンスを返す
return Future.delayed(Duration(seconds: 1), () {
return "f4";
});
}

await 実行関数 結果

awaitなし

(同期的)

main() {
  print("start");
  var hoge = f4();
  print(hoge);
  print("end");
}
start
Instance of 'Future<String>'
end

awaitあり

(非同期)

Future<void> main() async {
  print("start");
  var hoge = await f4();
  print(hoge);
  print("end");
}
start
f4
end

async/awaitをしないと、f4の処理の時間を待たず、インスタンスそのものが出力されます。async/awaitすると、futureインスタンスの処理を待ち、返り値を取得してから後続の処理へ続いてくれます。

 

以上がasync/awaitの処理の挙動結果となります。二度とこの辺の処理で悩まないようになれたらいいですね、、、!!