Kefir.js-JavaScriptの関数型リアクティブプログラミング(FRP)の新しいライブラリ

非同期コードを編成するためのFRPアプローチについては、すでに多くの人が聞いたことでしょう。 Habrで既にFRP( Haskellのリアクティブプログラミング 、Bacon.jsのFRP)について書いており、このテーマに関する良いレポートがあります( FRPとBacon.jsを使用したUIのプログラミングFunctional Reactive Programming&ClojureScriptJuha PaananenのBacon.jsについて-著者ベーコン



要するに、FRPはPromiseに似たアプローチですが、戻り値の数に制限はなく、イベントストリームを結合/変更するためのより多くの方法があります。 つまり、Promiseを使用して、まだ持っていない値を、すでに持っているかのように操作できる場合、FRPでは、時間の経過とともに変化する値を、変化しないかのように操作できます。



コールバックと比較した場合の結果は次のとおりです。



1)イベントストリーム(イベントストリーム)および時間とともに変化する値(プロパティ/動作) は、最初のクラスのオブジェクトになります 。 これは、それらが関数に渡され、関数から返されることを意味します。



たとえば、ボタンのクリックを含むオブジェクト(イベントストリーム)を作成し、通常の変数を使用してできることをすべて実行できます-関数に渡す、関数から戻る、別のオブジェクトのプロパティとして保存するなど または、ブラウザウィンドウの現在のサイズを反映するオブジェクトを作成できます(値は時間とともに変化します)。



これにより、コード内の責任をより良く共有し、モジュールに分割し、より柔軟で短く管理しやすいコードを書くことができます。



たとえば、ドラッグストリームを返す関数を作成できます。 パラメータとして、ドラッグアンドドロップの開始、移動、ドラッグの終了の3つのストリームが必要です。 次に、この関数を渡すことができます。対応するマウスイベント(mousedown、mousemove、mouseup)のストリーム、またはタッチイベント(touchstart、touchmove、touchend)のいずれかです。 関数自体はイベントのソースについては何も知りませんが、抽象ストリームでのみ機能します。 ベーコンの実装例



2)明示的な状態



FRPの2番目の大きな利点は、明示的な状態管理です。 ご存知のように、状態はプログラムの複雑さの最も重要な原因の1つです。したがって、有能な管理により、より信頼性が高くサポートしやすいプログラムを作成できます。 Rich HickeyのSimple Simple Easyの複雑さに関する優れたレポート



FRPを使用すると、ほとんどのコードを「純粋な関数」で記述し、データフロー(データフロー)を明示的に(イベントストリームを使用して)制御したり、プロパティに状態を明示的に保存したりできます。







Kefir.js





JavaScript用の2つの主要なFRPライブラリがあります。これらはBacon.jsRxJSです。 ベーコンは関数型プログラミングの精神に近いようで、RxJSはOOPの世界のものです。 Rxには非常に理解しにくいドキュメントがあります。まず、多くのドキュメントがあり、次にソースコードから自動生成されたドキュメントのように、非常に正式なスタイルで記述されています。 つまり Rxは習得が難しく、使いにくいです。 ただし、Rxはより高速で、メモリの消費量も少なくなります。



後者の状況は、時々ベーコンのアキレス腱です。 ベーコンでscrollMonitorアナログを記述しようとしたときに最初に問題に気付きました。 FRPのすべての機能を備えた非常に優れたAPIであることが判明しましたが、 このストレステストを実行すると、すべてがハングアップしました。 判明したように、ベーコンは多くのメモリを消費し、頻繁なガベージコレクションはフリーズを引き起こします。 これは、多数のストリームまたはモバイルデバイスで当てはまる場合があります。 アプリケーションコードを記述するときにこれについて考えることを減らすには、ライブラリのパフォーマンスのマージンを大きくする必要があると思います。



Kefir.jsは、私が過去数か月間取り組んできた新しいFRPライブラリです。 Kefir APIはBacon APIと非常に似ていますが、Kefirではパフォーマンスとメモリ消費に多くの注意を払っています。 現在、KefirはBaconの約5〜10倍、Rxの1〜2倍の速度で、メモリとほぼ同じです。



ライブテストにおけるケフィアとベーコンのパフォーマンスベンチマーク合成記憶テストの結果もあります 。 総合的なパフォーマンステストはまだありますが、それらの一部の結果を次に示します。



stream.map(id) ---------------------------------------------------------------- Kefir x 7,692,055 ops/sec ±1.62% (33 runs sampled) Bacon x 703,734 ops/sec ±1.63% (34 runs sampled) RxJS x 2,303,480 ops/sec ±1.70% (34 runs sampled) ----------------------- Kefir 1.00 Bacon 0.09 RxJS 0.30 stream.map(id) with multiple listeners ---------------------------------------------------------------- Kefir x 4,185,280 ops/sec ±0.89% (34 runs sampled) Bacon x 421,695 ops/sec ±0.79% (33 runs sampled) RxJS x 604,156 ops/sec ±1.21% (31 runs sampled) ----------------------- Kefir 1.00 Bacon 0.10 RxJS 0.14 stream.flatMap (x) -> Lib.once(x) ---------------------------------------------------------------- Kefir x 1,073,871 ops/sec ±1.14% (32 runs sampled) Bacon x 57,474 ops/sec ±4.45% (28 runs sampled) ----------------------- Kefir 1.00 Bacon 0.05 stream.combine(Lib.constant(1), fn) ---------------------------------------------------------------- Kefir x 2,413,356 ops/sec ±1.14% (34 runs sampled) Bacon x 220,898 ops/sec ±1.41% (34 runs sampled) ----------------------- Kefir 1.00 Bacon 0.09 stream.skipDuplicates() ---------------------------------------------------------------- Kefir x 7,009,320 ops/sec ±1.49% (33 runs sampled) Bacon x 684,319 ops/sec ±1.55% (34 runs sampled) RxJS x 401,798 ops/sec ±1.48% (31 runs sampled) ----------------------- Kefir 1.00 Bacon 0.10 RxJS 0.06
      
      







また、UnderscoreやLoDashのように、Kefirをできるだけ簡単に習得できるようにしています。 したがって、 ドキュメントは Underscoreのドキュメントに非常に似ています。 目標は、ドキュメントをRxとBaconの両方よりも改善することです。



Kefirのもう1つの目標は、ベーコンAPIを再考することです。 ベーコンは長い間進化してきましたが、下位互換性を維持する必要があるため、APIは一部の場所で少し扱いに​​くいものになりました。 ケフィアにはすべてをゼロから書く機会があり、私はこの機会を利用しようとしています。



現状




ケフィアは現在開発中ですが、まだやるべきことがたくさんあります。あなたはそれを使うことができます。 ドキュメントもまだ完全ではありませんが、すぐに追加し、新しい機能を追加するときに完全な状態に維持したいと考えています。



ベーコンと比較して、ケフィアには以下が欠けています。







今のところケフィアについてお伝えしたかったのはそれだけです。 ライブラリ自体を詳細に説明しませんでした。 ケフィアはベーコンに非常に似ており、ベーコンに精通していれば、最初のものを簡単に習得できます。 そうでない場合は、ケフィアのドキュメントを見て、ベーコンのチュートリアルでケフィアを学ぶことができます:-)



github.com/pozadi/kefir-GitHubのプロジェクト

pozadi.github.io/kefir-ドキュメント



All Articles