コンテンツにスキップ

利用者:Pute293/Async/await

Async/await

  • いくつかの言語での使用例が書いてあるものの、言語の選定基準について記載が無いためただの羅列に見える。各言語でのセマンティクスや実装方法の違いが分からない。
  • 使用例のコードがばらばらで統一感が無い。
  • 背景が欲しい

async/awaitとは、いくつかのプログラミング言語で利用可能な、主に非同期処理を簡潔に記述するための機能である。構文として提供する言語が多いが、一部の言語ではマクロやライブラリとして提供される。

async/await 導入の背景

[編集]
  • 典型的な非同期処理としてGUIの処理、通信などがある
  • 通信を例にとると、①通信前の処理、②通信開始、③通信後の処理について、③は②の後、レスポンスが返ってからでないと処理できない
  • 対応策として、(1)実際にレスポンスが返ってくるまで処理を止めて待つ(ブロッキング)か、(2)③の内容を処理系に登録しておき、適当なタイミングで呼び出してもらう必要がある
  • (1)の場合、この処理を行っているスレッド(に相当するもの)は処理が返ってくるまで応答しなくなる。
  • (2)の場合はブロッキングは起きない。ただし③の処理内容によっては極めて分かりづらい記述になる。また例外処理については別途検討が必要になる。

(例:コールバック地獄) たとえば以下の処理を考える。 1. クライアントはサーバに情報を送る。たとえばゲームで主人公の装備を変更するなら、変更前と変更後の装備を特定するIDを送るかも知れない。 ...

async/await を使用するコードの例

[編集]

async/awaitは、上記のコードを以下のように書けるようにするための機能である。

...

歴史

[編集]

promise パターン

Haskell

GHCのSimon MarlowがMicrosoftにいた

各言語におけるコードの例と実装

[編集]

やっていることはコルーチンを生成すること。非同期に結果を期待する場合は Promise

  • 非同期処理
  • コンパイラ

言語によって異なるが、

C#, VB

[編集]

処理の開始~最初のawaitまでが一塊の処理単位となる。以降はawait~await間が処理単位となる。 自分が今どの処理単位にいるかによって実行内容を変えるため、コンパイラが状態遷移機械を用いたコードを自動生成する。 本質的にコルーチンであり、イテレータブロックとほぼ同じコードを生成する。違いはyieldで値を返さずに実行コンテキストを切り替えること。

Python

[編集]

組み込み型としてコルーチンが存在する。async関数はコルーチンを生成して返す。



パターンは、いくつか 多くのプログラミング言語における構文機能であり、非同期非ブロッキング関数を通常の同期関数と同様の方法で構築できる。それは意味的にコルーチンの概念と関連し、多くの場合は類似した技術を使用して実装される。主に実行時間の長い非同期タスクの完了を待っている間に他のコードを実行する機会の提供を目的とし、通常は promise または同様のデータ構造で表される。

この機能はC# 5.0、VB.NET 11、Python 3.5、Hack、Dart、Kotlin 1.1、Rust 1.39[1]、Nim 0.9.4[2]、ECMAScript (JavaScript) 2017 (ES2017)、C++20にて利用できるほか、Scala[3]などでもいくつかの拡張、ベータ版、および特定の実装において実験的な成果物がある。