1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Fluter それ誤解?Futureを即時関数などで済ませようとする罠

1
Last updated at Posted at 2021-09-16

こんにちは。Flutterでは切っても切り離せないFutureのお話。

世界中の老若男女が考えるであろう、

「Futureめんどいから、もうそのまま実行してくれね?」

という願望。私も常々そう思い、ことある毎にGoogle巡礼しています。その中でよく目にする、即時関数やその他その場で実行している感のあるスクリプト。

用途によっては全然良いのですが、場合によってはやばいかも知れません。

前置き。awaitできないケース

色々ありますが、例えばコンストラクタではawait出来ません。

やっちまったCase1: Futureの中でasync awaitする

次の例を見てください。

main() {
  Future(() async {
    await Future.delayed(Duration(seconds: 1));
    print("future");
  });
  print("now");
}

私は最初これを見た時、歓喜に打たれてオレンジジュースを飲み干しました。Futureめんどい問題が見事に解決されている、awaitも入っているので、きっとfutureが先に出力されて、その後にnowが来るだろう。そう思ってオレンジジュースを注ぎました。実際に動かしてみると、結果は次のようになります。

now
future

なぜでしょう。

原因

Futureに渡している関数自体はasyncです。これは非同期ですので、実装は知りませんが、概念的には別スレッドで飛び立って、残されたスレッドは粛々と次の作業に移るわけですね。この非同期を繋ぎ止めるのがawaitですが、このスクリプト、awaitはasyncの中にしかありません。つまり別スレッドとして飛び立ったあと、その中でawaitしているわけです。これでは、普通の非同期と変わりありませんね。

やっちまったCase2: 即時関数でやっちまう

次の例を見てください。

main() {
  () async {
    await Future.delayed(Duration(seconds: 1));
    print("future");
  }();
  print("now");
}
now
future

これも同じです。即時関数ですぐに実行しているので、非同期から解放されて地に足のついた感がありますが、実はまだ非同期です。先程と同様、awaitが中に入っているだけですので、即時関数自体は非同期になっています。

終わりに

いかがでしたでしょうか。ちなみに私はFlutter赤ん坊ですので、間違いなどあるかも知れません。ご指摘いただけましたら幸いです。

以上です。

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?