目次

非同期サポート

Dartライブラリには、FutureまたはStreamオブジェクトを返す関数が多数含まれています。これらの関数は*非同期*です。つまり、時間のかかる可能性のある操作(I/Oなど)の設定後、その操作が完了するのを待たずに返ります。

asyncおよびawaitキーワードは非同期プログラミングをサポートしており、同期コードとよく似た非同期コードを記述できます。

Futureの処理

#

完了したFutureの結果が必要な場合は、2つの選択肢があります。

asyncawaitを使用するコードは非同期ですが、同期コードによく似ています。たとえば、awaitを使用して非同期関数の結果を待機するコードを次に示します。

dart
await lookUpVersion();

awaitを使用するには、コードはasync関数(asyncとマークされた関数)内になければなりません。

dart
Future<void> checkVersion() async {
  var version = await lookUpVersion();
  // Do something with version
}

awaitを使用するコードでは、trycatchfinallyを使用してエラー処理とクリーンアップを行います。

dart
try {
  version = await lookUpVersion();
} catch (e) {
  // React to inability to look up the version
}

async関数ではawaitを複数回使用できます。たとえば、次のコードは関数の結果を3回待機します。

dart
var entrypoint = await findEntryPoint();
var exitCode = await runExecutable(entrypoint, args);
await flushThenExit(exitCode);

await では、の値は通常Futureです。そうでない場合、値は自動的にFutureにラップされます。このFutureオブジェクトは、オブジェクトを返すことを約束を示します。await の値はその返されたオブジェクトです。await式により、そのオブジェクトが利用可能になるまで実行が一時停止します。

awaitを使用するときにコンパイル時エラーが発生する場合は、awaitasync関数内にあることを確認してください。 たとえば、アプリのmain()関数でawaitを使用するには、main()の本体をasyncとしてマークする必要があります。

dart
void main() async {
  checkVersion();
  print('In main: version is ${await lookUpVersion()}');
}

Future、asyncawaitの使用に関するインタラクティブな入門については、非同期プログラミングチュートリアルを参照してください。

非同期関数の宣言

#

async関数は、その本体がasync修飾子でマークされている関数です。

関数にasyncキーワードを追加すると、Futureが返されるようになります。たとえば、Stringを返す同期関数を次に示します。

dart
String lookUpVersion() => '1.0.0';

将来の実装に時間がかかるため、これをasync関数に変更すると、返される値はFutureになります。

dart
Future<String> lookUpVersion() async => '1.0.0';

関数の本体でFuture APIを使用する必要はありません。Dartは必要に応じてFutureオブジェクトを作成します。関数が役に立つ値を返さない場合は、その戻り型をFuture<void>にします。

Future、asyncawaitの使用に関するインタラクティブな入門については、非同期プログラミングチュートリアルを参照してください。

Streamの処理

#

Streamから値を取得する必要がある場合は、2つの選択肢があります。

  • asyncと*非同期forループ*(await for)を使用します。
  • dart:asyncドキュメントで説明されているように、Stream APIを使用します。

非同期forループは次の形式です。

dart
await for (varOrType identifier in expression) {
  // Executes each time the stream emits a value.
}

の値はStream型である必要があります。実行は次のとおりです。

  1. ストリームが値を発行するまで待機します。
  2. 変数をその発行された値に設定して、forループの本体を実行します。
  3. ストリームが閉じられるまで1と2を繰り返します。

ストリームへのリスニングを停止するには、breakまたはreturnステートメントを使用できます。これにより、forループから抜け出し、ストリームの購読が解除されます。

非同期forループを実装するときにコンパイル時エラーが発生する場合は、await forasync関数内にあることを確認してください。 たとえば、アプリのmain()関数で非同期forループを使用するには、main()の本体をasyncとしてマークする必要があります。

dart
void main() async {
  // ...
  await for (final request in requestServer) {
    handleRequest(request);
  }
  // ...
}

Dartの非同期プログラミングサポートの詳細については、dart:asyncライブラリドキュメントを参照してください。