私はさまざまなプラットフォームで Reactive Extensions を試していますが、少し気になるのはグリッチです。
UIコードの場合、これらのグリッチはそれほど問題にはならないかもしれませんが、通常はそれらを回避する演算子を見つけることができますが、グリッチがあるとコードのデバッグがより難しくなります.中間結果はデバッグにとって重要ではありませんが、私の心結果がいつ中間または「最終」であるかはわかりません。
Haskell と同期データ フロー システムで純粋な関数型 FRP を少し使用したことで、それも「間違っている」ように感じましたが、それはもちろん主観的なものです。
しかし、RX を非 UI アクチュエーター (モーターやスイッチなど) に接続する場合、グリッチがより問題になると思います。正しい値のみが外部アクチュエータに送信されるようにするにはどうすればよいでしょうか?
おそらく、これは、最終結果をアクチュエータに転送する前にすべての内部イベントが処理されるように、「外部センサー」がいつ開始イベントを発生させたかを知っている「ディスパッチャ」によって解決できる可能性があります。フラップジャックスの論文に記載されているようなもの。
私が答えを得たいと思っている質問は次のとおりです。
- RX に同期通知の不具合を修正できないものはありますか?
- そうでない場合、同期グリッチを修正する RX 用の (できれば製品品質の) ライブラリまたはアプローチは存在しますか? 特にシングルスレッド Javascript の場合、これは理にかなっているでしょうか?
- 一般的な解決策が存在しない場合、RX を使用して外部センサー/アクチュエーターをアクチュエーターでグリッチなしで制御するにはどうすればよいでしょうか?
例を挙げましょう
(a,b)コントラクトが存在する一連のタプルを出力したいとします。
a=n b=10 * floor(n/10)
n は自然数ストリーム = 0,1,2....
だから私は次のシーケンスを期待しています
(a=0, b=0)
(a=1, b=0)
(a=2, b=0)
...
(a=9, b=0)
(a=10, b=10)
(a=11, b=10)
...
RX では、より興味深いものにするために、b ストリームの計算にフィルターを使用します。
var n = Observable
.Interval(TimeSpan.FromSeconds(1))
.Publish()
.RefCount();
var a = n.Select(t => "a=" + t);
var b = n.Where(t => t % 10 == 0)
.Select(t => "b=" + t);
var ab = a.CombineLatest(b, Tuple.Create);
ab.Subscribe(Console.WriteLine);
これにより、私がグリッチであると信じていたものが得られます(不変条件/契約の一時的な違反):
(a=0, b=0)
(a=1, b=0)
(a=2, b=0)
...
(a=10, b=0) <-- glitch?
(a=10, b=10)
(a=11, b=10)
これが CombineLatest の正しい動作であることは理解していますが、実際の純粋な FRP システムでは、これらの中間の不変条件に違反する結果が得られないため、これはグリッチと呼ばれていると思いました。
この例では、Zip を使用できないことに注意してください。また、WithLatestFrom を使用すると誤った結果が返されることに注意してください。
もちろん、この例を 1 つのモナド計算に単純化して、n 個のストリームの出現をマルチキャストしないようにすることもできます (これは、フィルター処理ができず、単にマップすることを意味します)。 ' 監視可能なストリームを分割して再結合するたびに:
s
/ \
a b
\ /
t
たとえば、FlapJAX では、これらの問題は発生しません。
これは意味がありますか?
どうもありがとう、ピーター