| リアクティブX | |
|---|---|
![]() | |
| その他の名前 | リアクティブ拡張機能 |
| 原作者 | マイクロソフト |
| 開発者 | ReactiveXの貢献者 |
| リリース | 2011年6月 21日 ( 2011-06-21 ) |
| 執筆 | Java、Scala、C#、C++、Clojure、JavaScript、Python、Groovy、JRuby、その他 |
| プラットフォーム | クロスプラットフォーム |
| タイプ | API |
| ライセンス | Apache License 2.0、MITライセンス |
| Webサイト | reactivex.io |
| リポジトリ | github.com/ReactiveX |
ReactiveX(Rx、別名Reactive Extensions )は、 Microsoftが開発したソフトウェアライブラリで、命令型プログラミング言語が、データが同期か非同期かに関わらず、データシーケンスを操作できるようにします。シーケンス内の各項目を操作する一連のシーケンス演算子を提供します。これはリアクティブプログラミングの実装であり、複数のプログラミング言語で実装されるツールの設計図を提供します。
ReactiveXは、オブザーバブルストリームを使用した非同期プログラミングのためのAPIです。[ 1 ]
非同期プログラミングでは、プログラマーは関数を呼び出し、その関数が完了したときに「コールバック」を実行させることができます。これは通常、関数に完了時に実行する別の関数のアドレスを指定することで実現されます。このように設計されたプログラムは、多数のスレッドが頻繁に起動と停止を繰り返すことによるオーバーヘッドを回避できる場合が多いです。
リアクティブ拡張機能におけるオブザーバブルストリーム(つまり、監視可能なストリーム)は、next、error、completeの3つのイベントを発行するイベントエミッターのようなものです。オブザーバブルは、errorイベントまたはcompleteイベントを発行するまでnextイベントを発行し続けます。ただし、その時点では、再度購読されない限り、それ以上のイベントは発行されません。
以下の例では、JavaScriptプログラミング言語用のリアクティブ拡張機能であるRxJSを使用しています。
データシーケンスの場合、イテレータの利点とイベントベースの非同期プログラミングの柔軟性を兼ね備えています。また、シンプルなプロミスとしても機能し、複数のコールバック層によって生じる複雑な処理の連鎖を解消します。
ReactiveXは、オブザーバーパターンとイテレータパターン、そして関数型プログラミングのアイデアを組み合わせたものです。[ 2 ]
オブザーバーは、オブザーバブルシーケンスを購読します。シーケンスは、通常、指定されたコールバック関数を呼び出すことで、項目を1つずつオブザーバーに送信します。オブザーバーは、次の項目を処理する前に、それぞれの項目を処理します。非同期で多数のイベントが発生した場合は、それらをキューに格納するか、破棄する必要があります。ReactiveXでは、オブザーバーは、項目が順不同で呼び出されたり、(マルチスレッド環境では)前の項目のコールバックが完了する前に呼び出されたりすることはありません。非同期呼び出しは非同期のままであり、オブザーバブルを返すことで処理できます。
これはイテレータパターンに似ており、致命的なエラーが発生した場合は、別の関数を呼び出すことでオブザーバに個別に通知します。すべての項目が送信されると、処理が完了し、(3番目の関数を呼び出すことでオブザーバに通知します)。Reactive Extensions APIは、他のプログラミング言語のイテレータ演算子から多くの演算子を借用しています。
リアクティブ拡張機能は、関数型リアクティブプログラミングとは異なります。その詳細は「リアクティブ拡張機能入門」で説明されています。
これは「関数型リアクティブプログラミング」と呼ばれることもありますが、これは誤称です。ReactiveX は関数型であり、リアクティブであるかもしれませんが、「関数型リアクティブプログラミング」は全く別のものです。主な違いの 1 つは、関数型リアクティブプログラミングは時間とともに連続的に変化する値を扱うのに対し、ReactiveX は時間とともに放出される離散的な値を扱うことです。(関数型リアクティブプログラミングに関するより正確な情報については、Conal Elliott の著作を参照してください。)[ 2 ]
演算子は、最初の引数として1つのオブザーバブル(ソース)を受け取り、別のオブザーバブル(デスティネーション、または外部オブザーバブル)を返す関数です。ソースオブザーバブルが発行する各項目に対して、その項目に関数を適用し、デスティネーションオブザーバブルに発行します。さらに、デスティネーションオブザーバブルに別のオブザーバブルを発行することもできます。これは内部オブザーバブルと呼ばれます。
内部オブザーバブルを発行する演算子の後には、すべての内部オブザーバブルによって発行された項目を何らかの方法で組み合わせ、その項目を外部オブザーバブルに発行する別の演算子が続くことができます。例:
switchAll– 新しい内部オブザーバブルが発行されるとすぐに購読し、以前のオブザーバブルの購読を解除します。mergeAll– 内部の観測可能オブジェクトが発行されると同時にそれらを購読し、受信した順序に関係なくその値を出力します。concatAll– 各内部オブザーバブルを順番に購読し、次のオブザーバブルを購読する前に、それが完了するのを待ちます。演算子を連結することで、特定の基準に基づいてイベントをフィルタリングする複雑なデータフローを作成できます。同じ観測対象に対して複数の演算子を適用することも可能です。
Reactive Extensions で使用できる演算子の中には、map、reduce、group、zip など、関数型プログラミング言語を使用するプログラマーには馴染みのあるものがあるかもしれません。[ 3 ] Reactive Extensions には他にも多くの演算子がありますが、プログラミング言語の特定の実装で使用できる演算子は異なる場合があります。
ここでは、map演算子とreduce演算子の使用例を示します。数値のリストからobservableを作成します。map演算子は各数値を2倍してobservableを返します。reduce演算子は、渡されたすべての数値を合計します(0は開始値です)。subscribeを呼び出すと、一連の演算子によって生成されたobservableの値を監視するオブザーバーが登録されます。subscribeメソッドを使用すると、observableでエラーが発生するたびに呼び出されるエラー処理関数と、observableがアイテムの発行を完了したときに呼び出される完了関数を渡すことができます。
import { of , Observable , map , reduce } from 'rxjs' ;const source : Observable <number> = of ( 1 , 2 , 3 , 4 , 5 ) ; source.pipe ( map ( ( value ) => value * 2 ) , reduce (( sum , value ) = > sum + value , 0 ) ) . subscribe ({ next : ( value ) => { console.log ( value ); }, error : ( error ) => { console.error ( error ) ; }, complete : ( ) => { console.log ( ' done ' ) ; } , } );RxJS の特定のプリミティブを使用すると、BehaviorSubject任意の複雑さのアプリケーションの状態を追跡するための純粋なステートフル ストリームを簡単に作成できます。
下のボタンをクリックすると、イベントがストリームに送信され、ストリームは毎回次の自然数を再送信して、後続のタグに送り返し、検出されたクリック数を表示します。<span>
Rimmel.jsなどのライブラリは、RxJS Observableを中心に設計されており、リアクティブストリームとHTML DOMの統合を可能にします。
import { BehaviorSubject , scan } from 'rxjs' ; import { rml } from 'rimmel' ;const count = new BehaviorSubject ( 0 ) .pipe ( scan ( x => x + 1 ) );document.body.innerHTML = rml ` < button onclick=" ${ counter } " >click</button> <p> カウントは: <span> ${ count } </span></p> ` ;Reactive Extensionsは、2011年頃、 Microsoftのクラウドプログラマビリティチームによって、Voltaと呼ばれる大規模なプロジェクトの副産物として開発されました。当初は、Voltaにおける階層分割をサポートするために、アプリケーション内の異なる階層間で発生するイベントを抽象化することを目的としていました。プロジェクトのロゴはデンキウナギを表しており、これはVoltaを象徴しています。名前の末尾にある「extensions」は、ほぼ同時期に開発されたParallel Extensionsテクノロジーを指しており、両者は相互補完的な関係にあると考えられています。
Rx の最初の実装は.NET Framework向けで、2011 年 6 月 21 日にリリースされました。その後、チームはJavaScriptやC++など、他のプラットフォーム向けの Rx の実装を開始しました。この技術は2012 年後半にオープンソースとして公開され、当初はCodePlexで公開されました。その後、コードはGitHubに移行され、Go、Java、Kotlin、PHP、Rust など、他のいくつかの言語にも移植されています。