ホームページ >ウェブフロントエンド >jsチュートリアル >RXJを使用した機能的な反応性プログラミングの紹介
リアクティブプログラミングの原則は、JavaScriptにとって完全に新しいものではありません。すでにプロパティバインディング、EventeMitterパターン、node.jsストリームなどがあります。これらの方法の優雅さには、パフォーマンスの低下、過度に複雑な抽象化、またはデバッグの問題が伴う場合があります。通常、これらの欠点は、新しい抽象化レイヤーの利点と比較して最小限です。もちろん、私たちの最小限の例は、通常のアプリケーションを反映するのではなく、可能な限り短く、簡潔にします。
これ以上苦労せずに、JavaScript(RXJS)ライブラリ用のリアクティブな拡張機能を演奏して、手を汚してみましょう。 RXJSは多くのチェーンを使用しています。これは、jQueryなどの他のライブラリでも使用される人気のある手法です。メソッドチェーンのガイド(Rubyのコンテキスト)はSitePointで入手できます。
ストリームの例一般に、内部と外部の2種類のストリームを区別できます。前者は人工的で私たちのコントロールの範囲内であると見なすことができますが、後者は私たちのコントロールを超えた情報源から来ています。外部ストリームは、コードから(直接的または間接的に)トリガーされる場合があります。
通常、ストリームは私たちを待っていません。それらを処理できるかどうかにかかわらず、それらは起こります。たとえば、道路で車を観察したい場合、車の流れを再起動することはできません。ストリームは、私たちがそれを観察するかどうかとは無関係に起こります。 RX用語では、これをahot Observable
と呼びます。 rxはcold observablesも紹介します。これは、標準の反復因子のように振る舞い、ストリームからの情報が各オブザーバーのすべてのアイテムで構成されているようになります。 次の画像は、いくつかの外部の種類のストリームを示しています。 (以前は開始された)リクエストと、一般的にセットアップされたWebフックと、マウスやキーボードの対話などのUIイベントが言及されていることがわかります。最後に、GPSセンサー、加速度計、またはその他のセンサーなど、デバイスからデータを受け取ることもあります。
この画像には、
メッセージとして記載されている1つのストリームも含まれていました。メッセージはいくつかの形式で表示されます。最もシンプルなフォームの1つは、当社のWebサイトと他のWebサイトの間のコミュニケーションです。その他の例には、WebSocketまたはWebワーカーとのコミュニケーションが含まれます。後者のコードの例を見てみましょう。
労働者のコードを以下に示します。コードは、2〜10のプライムナンバーを見つけようとします
。数値が見つかったら、結果が報告されます 古典的には、Webワーカー(ファイルPrime.jsにあると想定)が次のように含まれています。簡潔にするために、Webワーカーのサポートと返された結果の合法性のチェックをスキップします。
Webワーカーの詳細とJavaScriptを使用したマルチスレッドについては、Parallel.js。 上記の例を考慮して、プライム番号は正の整数の間で漸近分布に従うことを知っています。 xから∞の場合、x / log(x)の分布を取得します。これは、最初はより多くの数字が表示されることを意味します。ここでは、チェックもはるかに安価です(つまり、最初よりも時間の単位あたりのプライム数がはるかに多くなります。))
これは、結果のための単純な時間軸と塊で示すことができます:<span>(function (start<span>, end</span>) { </span> <span>var n = start - 1; </span> <span>while (n++ < end) { </span> <span>var k = Math.sqrt(n); </span> <span>var found = false; </span> <span>for (var i = 2; !found && i <= k; ++i) { </span> found <span>= n % i === 0; </span> <span>} </span> <span>if (!found) { </span> <span>postMessage(n.toString()); </span> <span>} </span> <span>} </span><span>})(2, 1e10); </span>
は、ユーザーの入力を検索ボックスに調べることで、関連していないが同様の例を挙げることができます。当初、ユーザーは検索するものを入力することに熱心な場合があります。ただし、彼の要求が具体的になるほど、キーストローク間の時差が大きくなります。ライブ結果を表示する能力を提供することは、ユーザーがリクエストを絞り込むのを支援するために、間違いなく望ましいことです。しかし、私たちが望んでいないのは、キーストロークごとにリクエストを実行することです。特に、最初のストロークは非常に速く実行され、考えられない、または専門化する必要性がないためです。
両方のシナリオで、回答は、特定の時間間隔で以前のイベントを集約することです。説明されている2つのシナリオの違いは、指定された時間間隔後に素数が常に表示されるべきであることです(つまり、プライム数の一部は、プレゼンテーションで潜在的に遅延している可能性があります)。対照的に、検索クエリは、指定された間隔中にキーストロークが発生しない場合にのみ、新しいリクエストをトリガーします。したがって、キーストロークが検出されると、タイマーがリセットされます。rxjsへの救助
RXJの基本的なビルディングブロックは、観測可能性(生産者)とオブザーバー(消費者)です。既に2種類のオブザーバブルについて言及しました:
熱い観測可能性は、私たちがそれらに購読されていない場合でも押しています(例えば、UIイベント)。
観察可能なものを購読することは、観察可能な種類とは無関係です。両方のタイプについて、OnNext、Onerror、およびOncompletedで構成される通知文法の基本的な要件を満たす3つの機能を提供できます。 onnextコールバックは必須です
<span>(function (start<span>, end</span>) { </span> <span>var n = start - 1; </span> <span>while (n++ < end) { </span> <span>var k = Math.sqrt(n); </span> <span>var found = false; </span> <span>for (var i = 2; !found && i <= k; ++i) { </span> found <span>= n % i === 0; </span> <span>} </span> <span>if (!found) { </span> <span>postMessage(n.toString()); </span> <span>} </span> <span>} </span><span>})(2, 1e10); </span>ベストプラクティスとして、廃棄方法を使用してサブスクリプションを終了する必要があります。これにより、必要なクリーンアップステップが実行されます。それ以外の場合は、ガベージコレクションが未使用のリソースのクリーンアップを防ぐことができるかもしれません。
購読なしに、可変観測可能な変数に含まれる観察可能なものは、単なる風邪の観測可能です。それにもかかわらず、パブリッシュメソッドを使用して、ホットシーケンス(つまり、擬似サブスクリプションを実行する)に変換することも可能です。
<span>(function (start<span>, end</span>) { </span> <span>var n = start - 1; </span> <span>while (n++ < end) { </span> <span>var k = Math.sqrt(n); </span> <span>var found = false; </span> <span>for (var i = 2; !found && i <= k; ++i) { </span> found <span>= n % i === 0; </span> <span>} </span> <span>if (!found) { </span> <span>postMessage(n.toString()); </span> <span>} </span> <span>} </span><span>})(2, 1e10); </span>RXJに含まれるヘルパーの一部は、既存のデータ構造の変換のみを扱います。 JavaScriptでは、それらの3つを区別することができます:
rxjsは、非同期的な(戻り)バリューサポートを提供するためにデータ型をもたらすようになりました。したがって、4つの象限が記入されました。
反復因子を引く必要がある間、観測可能性の値はプッシュされます。例は、次のイベントを強制することはできないイベントストリームです。イベントループによって通知されるのを待つことしかできません。
オブザーバブルズを作成または処理するヘルパーのほとんどは、サブスクリプションが開始されたときと通知が公開されるときを制御するスケジューラを受け入れます。デフォルトのスケジューラはほとんどの実用的な目的で正常に機能するため、ここでは詳しく説明しません。 RXJSの多くのオペレーターは、スロットル、間隔、または遅延などの同時性を導入します。ここで、これらのヘルパーが不可欠になる前の例をもう一度見てみましょう。
<span>var worker = new Worker('prime.js'); </span>worker<span>.addEventListener('message', function (ev) { </span> <span>var primeNumber = ev.data * 1; </span> <span>console.log(primeNumber); </span><span>}, false); </span>例
最初に、プライムナンバージェネレーターを見てみましょう。特定の時間にわたって結果を集約したかったので、UI(特に最初に)があまりにも多くの更新に対処する必要がないようにしました。
ここでは、実際には、前述のインターバルヘルパーと組み合わせてRXJのバッファ関数を使用することをお勧めします。
結果は、次の図で表す必要があります。緑色の塊は、指定された時間間隔(間隔の構築に使用される時間)の後に発生します。バッファーは、そのような間隔中に、見たすべての青い塊を集約します。さらに、マップを導入することもできます。これにより、データの変換に役立ちます。たとえば、受信したイベントの引数を変換して、送信されたデータを数として取得することをお勧めします。
Fromevent関数は、標準のイベントエミッターパターンを使用して、任意のオブジェクトから観察可能なものを構築します。バッファーはまた、ゼロの長さで配列を返します。そのため、ストリームを空のアレイに縮小するための機能を導入します。最後に、この例では、生成された素数の数のみにのみ関心があります。したがって、バッファをマップしてその長さを取得します
もう1つの例は、検索クエリボックスです。これは、特定のアイドル時間の後にのみリクエストを開始するためにスロットする必要があります。このようなシナリオで役立つ可能性のある2つの機能があります。スロットル関数は、指定された時間枠内で最初のエントリを生成します。デバウンス関数は、指定されたタイムウィンドウ内で見られる最後のエントリを生成します。時間窓もそれに応じてシフトされます(つまり、最初 /最後の項目に対して)。
次の図に反映される動作を実現したいと考えています。したがって、デバウンスメカニズムを使用します。
このコードでは、ウィンドウは300msに設定されています。また、以前のクエリとは異なる少なくとも3文字の値の値のクエリを制限します。これにより、何かを入力して消去することで修正されたばかりの入力に対する不必要なリクエストが排除されます。 この表現全体には、2つの重要な部分があります。 1つは、クエリテキストのsearchforを使用したリクエストへの変換、もう1つはswitch()関数です。後者は、ネストされたオブザーバブルを返す関数を取り、最新の観測可能なシーケンスからのみ値を生成します。
リクエストを作成する関数は、次のように定義できます。<span>(function (start<span>, end</span>) { </span> <span>var n = start - 1; </span> <span>while (n++ < end) { </span> <span>var k = Math.sqrt(n); </span> <span>var found = false; </span> <span>for (var i = 2; !found && i <= k; ++i) { </span> found <span>= n % i === 0; </span> <span>} </span> <span>if (!found) { </span> <span>postMessage(n.toString()); </span> <span>} </span> <span>} </span><span>})(2, 1e10); </span>
ネストされた観測可能(無効な要求の場合は未定義になる可能性がある)に注意してください。
結論rxjsは、JavaScriptのリアクティブなプログラミングを楽しい現実にします。別の方法として、Bacon.jsも同様に機能します。それにもかかわらず、RXJSの最良のことの1つはRX自体で、多くのプラットフォームで利用できます。これにより、他の言語、プラットフォーム、またはシステムへの移行が非常に簡単になります。また、簡潔で構成可能な一連の方法で、リアクティブプログラミングの概念の一部を統合します。さらに、RXJS-DOMなど、いくつかの非常に有用な拡張機能が存在し、DOMとの相互作用を簡素化します。
どこでrxjsが輝いていると思いますか?
機能プログラミング(FP)と機能的反応性プログラミング(FRP)はどちらもプログラミングパラダイムですが、焦点が異なります。 FPは、計算を数学機能の評価として扱い、状態と変化可能なデータの変化を回避するプログラミングのスタイルです。命令的なプログラミングスタイルとは対照的に、関数の適用を強調します。これは、状態の変化を強調しています。
一方、FRPは非同期データストリームを扱うFPのバリアントです。リアクティブプログラミングモデルと機能プログラミングを組み合わせます。 FRPでは、静的(アレイなど)および動的(マウスクリック、Webリクエストなど)データストリームを表現し、変更に対応できます。 🎜> RXJS(JavaScriptのリアクティブ拡張機能)は、非同期またはコールバックベースのコードを簡単に作成できるようにするために、観測可能性を使用したリアクティブプログラミングのライブラリです。これにより、機能的なリアクティブプログラミングにぴったりです。 RXJSを使用すると、さまざまなソースからデータストリームを作成し、提供されたオペレーターを使用してこれらのデータストリームを変換、組み合わせ、操作、または反応できます。 RXJSのコアコンセプト。それらはデータストリームであり、時間の経過とともに複数の値を発する可能性があります。次に、エラー、および完了する3種類の値を放出できます。 「次の」値は任意のJavaScriptオブジェクトであり、「エラー」は何か問題が発生したときにエラーオブジェクトです。 >
約束と観察可能なものはどちらも非同期操作を扱っていますが、それをさまざまな方法で行います。約束とは、まだ利用できないかもしれない価値です。それは一度だけ解決することができます(充足または拒否されます)。一方、観察可能なものとは、ゼロ以上の値を発する可能性のある値のストリームであり、
以上がRXJを使用した機能的な反応性プログラミングの紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。