【Flutter/Dart】非同期処理(async/await)とは?Future型で解説

今回はFlutterの非同期処理(async/await)とは何かについて紹介します。

非同期処理であるFuture型のコードを使用しながら解説していきます。

\ 世界最大級のオンライン学習サービス /

目次

同期処理と非同期処理の違い

Flutterで非同期処理(async/await)の使い方を紹介する前に「同期処理」と「非同期処理」の違いについて触れておきます。

同期処理とは?

import 'dart:io';

main() {
  task1();
  task2();
  task3();
}

void task1() {
  print('タスク1完了');
}
void task2() {
  sleep(Duration(seconds: 5));
  print('タスク2完了');
}
void task3() {
  print('タスク3完了');
}

//結果
//タスク1完了
//タスク2完了 <-出力までに5秒かかる
//タスク3完了 <-task2が完了するまで待つ必要がある

同期処理とは複数のタスクを順に実行していく処理のことです。

同期処理では時間のかかる処理が途中にあると次の処理が実行できないデメリットがあります。上記コードでは時間がかかる「task2」の処理が完了するまで「task3」に移れません。

非同期処理とは?

main() {
  task1();
  task2();
  task3();
}

void task1() {
  print('タスク1完了');
}
void task2() {
  Future.delayed(Duration(seconds: 3), () => print('タスク2完了'));
}
void task3() {
  print('タスク3完了');
}

//結果
//タスク1完了
//タスク3完了 <-task2の非同期処理をスキップ
//タスク2完了

非同期処理とはある処理を実行している間に別の処理を実行できる処理のことです。

下のDartPadを実行すると「task2」で非同期処理Future.delayedの処理が完了する前に「task3」が実行されるのが分かります。

非同期処理の結果(返り値)を受け取るには?

main() {
  task1();
  String result = task2();
  task3(result);
}

void task1() {
  print('タスク1完了');
}

String task2() {
  String result = 'タスク2未完了';
  Future.delayed(Duration(seconds: 3), () {
    result = 'タスク2完了';
  });
  return result;
}

void task3(task2) {
  print('タスク2結果: $task2');
  print('タスク3完了');
}

//結果
//タスク1完了
//タスク2結果: タスク2未完了
//タスク3完了

上記コードでは「task2」の非同期処理Future.delayedで変数resultの値を変更する前(処理が完了する前)に、task3の引数としてresultが渡されてしまっています。

非同期処理では今回のように非同期処理の結果(返り値)が別の処理に反映されない恐れがあります。そうならないためにasyncawaitを使用します。

asyncとawaitの使い方

Future task2() async {
  String result = 'タスク2未完了';
  await Future.delayed(Duration(seconds: 3), () {
    result = 'タスク2完了';
  });
  return result;
}

先ほどの「task2」ではFuture.delayedの処理が完了する前に次の処理が実行されたのが問題でした。よって非同期処理が完了した後で次の処理を実行するようFuture.delayedの前にawaitを宣言します。

awaitを使用するには関数の波括弧の前にasyncをつける必要があります。またasyncを使用した返り値はFuture型(またはStream型)として扱います。

main() async {
  task1();
  String result = await task2();
  task3(result);
}

mainでも「task2」が完了する前に「task3」が実行されないよう、「task2」にawaitを宣言し、mainの波括弧の前にasyncをつけます。

これで非同期処理の返り値を別の処理で使用できます。下のDartPadで確認してみてください。

サンプルコード

main() async {
  task1();
  String result = await task2();
  task3(result);
}

void task1() {
  print('タスク1完了');
}

Future task2() async {
  String result = 'タスク2未完了';
  await Future.delayed(Duration(seconds: 3), () {
    result = 'タスク2完了';
  });
  return result;
}

void task3(task2) {
  print('タスク2結果: $task2');
  print('タスク3完了');
}

一緒に読みたい

参考

  • URLをコピーしました!
目次