意味
私の(自分の)お気に入りの定義:
グリッチは、観測可能な状態での一時的な矛盾です。
Scala.Rxからの定義:
FRP のコンテキストでは、グリッチはデータフロー グラフの一時的な不整合です。更新は瞬時に行われるのではなく、計算に時間がかかるため、更新プロセス中に FRP システム内の値が一時的に同期しなくなる場合があります。さらに、FRP システムの性質によっては、ノードが伝播で複数回更新される可能性があります。
例
整数変数a
、を考えてみましょうb
。などを定義sum
し、.prod
sum := a + b
prod := a * b
この例を JavaFX に書き直してみましょう。
IntegerProperty a = new SimpleIntegerProperty();
IntegerProperty b = new SimpleIntegerProperty();
NumberBinding sum = a.add(b);
NumberBinding prod = a.multiply(b);
それでは、少し一貫性チェックを書きましょう。
InvalidationListener consistencyCheck = obs -> {
assert sum.intValue() == a.get() + b.get();
assert prod.intValue() == a.get() * b.get();
};
sum.addListener(consistencyCheck);
prod.addListener(consistencyCheck);
a.set(1);
b.set(2);
次の理由により、このコードは最後の行でアサーション エラーで失敗します。
b
更新されます (2 に)
sum
更新されます(3に)
- `consistencyCheck` がトリガーされ、`a == 1`、`b == 2`、しかし `prod == 0`、`prod` がまだ更新されていないため
これはグリッチです —一時的におよび とprod
一致しません。a
b
ReactFX を使用したグリッチの除去
最初に、ReactFX はすぐに使用できる「グリッチ フリー」ではありませんが、グリッチを排除するためのツールを提供することに注意してください。それらを使用するための意識的な努力をしない限り、ReactFX は RX (例えば rxJava) よりグリッチフリーではありません。
ReactFX の不具合を解消する手法は、イベントの伝播が同期的であるという事実に依存しています。一方、RX でのイベント伝搬は常に非同期であるため、これらの手法を RX システムに実装することはできません。
sum
上記の例では、との両方prod
が更新されるまでリスナー通知を延期します。ReactFX でこれを実現する方法は次のとおりです。
import org.reactfx.Guardian;
import org.reactfx.inhibeans.binding.Binding;
IntegerProperty a = new SimpleIntegerProperty();
IntegerProperty b = new SimpleIntegerProperty();
Binding<Number> sum = Binding.wrap(a.add(b)); // Binding imported from ReactFX
Binding<Number> prod = Binding.wrap(a.multiply(b)); // Binding imported from ReactFX
InvalidationListener consistencyCheck = obs -> {
assert sum.getValue().intValue() == a.get() + b.get();
assert prod.getValue().intValue() == a.get() * b.get();
};
sum.addListener(consistencyCheck);
prod.addListener(consistencyCheck);
// defer sum and prod listeners until the end of the block
Guardian.combine(sum, prod).guardWhile(() -> {
a.set(1);
b.set(2);
});